android_webview
apps
ash
base
build
3pp_common
android
bytecode
docs
gradle
gtest_apk
gyp
proto
test
util
OWNERS
aar.py
aar.pydeps
aidl.py
aidl.pydeps
allot_native_libraries.py
allot_native_libraries.pydeps
apkbuilder.py
apkbuilder.pydeps
assert_static_initializers.py
assert_static_initializers.pydeps
binary_baseline_profile.py
binary_baseline_profile.pydeps
bundletool.py
bytecode_processor.py
bytecode_processor.pydeps
bytecode_rewriter.py
bytecode_rewriter.pydeps
check_flag_expectations.py
check_flag_expectations.pydeps
compile_java.py
compile_java.pydeps
compile_kt.py
compile_kt.pydeps
compile_resources.py
compile_resources.pydeps
copy_ex.py
copy_ex.pydeps
create_apk_operations_script.py
create_apk_operations_script.pydeps
create_app_bundle.py
create_app_bundle.pydeps
create_app_bundle_apks.py
create_app_bundle_apks.pydeps
create_bundle_wrapper_script.py
create_bundle_wrapper_script.pydeps
create_java_binary_script.py
create_java_binary_script.pydeps
create_r_java.py
create_r_java.pydeps
create_r_txt.py
create_r_txt.pydeps
create_size_info_files.py
create_size_info_files.pydeps
create_stub_manifest.py
create_test_apk_wrapper_script.py
create_test_apk_wrapper_script.pydeps
create_ui_locale_resources.py
create_ui_locale_resources.pydeps
create_unwind_table.py
create_unwind_table_tests.py
dex.py
dex.pydeps
dex_test.py
dist_aar.py
dist_aar.pydeps
extract_unwind_tables.py
extract_unwind_tables_tests.py
filter_zip.py
filter_zip.pydeps
finalize_apk.py
find.py
flatc_java.py
flatc_java.pydeps
gcc_preprocess.py
gcc_preprocess.pydeps
generate_android_wrapper.py
generate_linker_version_script.py
generate_linker_version_script.pydeps
ijar.py
ijar.pydeps
jacoco_instr.py
jacoco_instr.pydeps
java_cpp_enum.py
java_cpp_enum.pydeps
java_cpp_enum_tests.py
java_cpp_features.py
java_cpp_features.pydeps
java_cpp_features_tests.py
java_cpp_strings.py
java_cpp_strings.pydeps
java_cpp_strings_tests.py
java_google_api_keys.py
java_google_api_keys.pydeps
java_google_api_keys_tests.py
javac_output_processor.py
jinja_template.py
jinja_template.pydeps
lint.py
lint.pydeps
merge_manifest.py
merge_manifest.pydeps
nocompile_test.py
optimize_resources.py
optimize_resources.pydeps
prepare_resources.py
prepare_resources.pydeps
process_native_prebuilt.py
process_native_prebuilt.pydeps
proguard.py
proguard.pydeps
system_image_apks.py
system_image_apks.pydeps
trace_event_bytecode_rewriter.py
trace_event_bytecode_rewriter.pydeps
turbine.py
turbine.pydeps
unused_resources.py
unused_resources.pydeps
validate_inputs.py
validate_static_library_dex_references.py
validate_static_library_dex_references.pydeps
write_build_config.py
write_build_config.pydeps
write_native_libraries_java.py
write_native_libraries_java.pydeps
zip.py
zip.pydeps
incremental_install
java
junit
native_flags
pylib
stacktrace
test
test_wrapper
tests
unused_resources
update_deps
AndroidManifest.xml
BUILD.gn
COMMON_METADATA
CheckInstallApk-debug.apk
DIR_METADATA
OWNERS
PRESUBMIT.py
adb_chrome_public_command_line
adb_command_line.py
adb_gdb
adb_install_apk.py
adb_logcat_monitor.py
adb_logcat_printer.py
adb_profile_chrome
adb_profile_chrome_startup
adb_reverse_forwarder.py
adb_system_webengine_command_line
adb_system_webview_command_line
android_only_explicit_jni_exports.lst
android_only_jni_exports.lst
apk_operations.py
apk_operations.pydeps
asan_symbolize.py
chromium-debug.keystore
chromium_annotations.flags
connect_lldb.sh
convert_dex_profile.py
convert_dex_profile_tests.py
dcheck_is_off.flags
devil_chromium.json
devil_chromium.py
devil_chromium.pydeps
diff_resource_sizes.py
download_doclava.py
dump_apk_resource_strings.py
envsetup.sh
fast_local_dev_server.py
generate_jacoco_report.py
generate_vscode_classpath.py
host_heartbeat.py
lighttpd_server.py
list_class_verification_failures.py
list_class_verification_failures_test.py
list_java_targets.py
method_count.py
provision_devices.py
pylintrc
resource_sizes.gni
resource_sizes.py
resource_sizes.pydeps
screenshot.py
test_runner.py
test_runner.pydeps
tombstones.py
update_verification.py
video_recorder.py
apple
args
chromeos
cipd
config
docs
fuchsia
gn_ast
internal
ios
lacros
linux
mac
private_code_test
rust
sanitizers
skia_gold_common
toolchain
util
win
.gitignore
.style.yapf
BUILD.gn
DIR_METADATA
OWNERS
OWNERS.setnoparent
OWNERS.status
PRESUBMIT.py
PRESUBMIT_test.py
README.md
action_helpers.py
action_helpers_unittest.py
build-ctags.sh
build_config.h
buildflag.h
buildflag_header.gni
check_gn_headers.py
check_gn_headers_unittest.py
check_gn_headers_whitelist.txt
check_return_value.py
ciopfs.sha1
clobber.py
clobber_unittest.py
compiled_action.gni
compute_build_timestamp.py
copy_test_data_ios.py
cp.py
del_ninja_deps_cache.py
detect_host_arch.py
dir_exists.py
dotfile_settings.gni
download_nacl_toolchains.py
env_dump.py
extract_from_cab.py
extract_partition.py
find_depot_tools.py
fix_gn_headers.py
gdb-add-index
get_landmines.py
get_symlink_targets.py
gn_editor
gn_helpers.py
gn_helpers_unittest.py
gn_logs.gni
gn_run_binary.py
install-build-deps.py
install-build-deps.sh
install-chroot.sh
landmine_utils.py
landmines.py
locale_tool.py
mac_toolchain.py
metadata.json.in
nocompile.gni
noop.py
partitioned_shared_library.gni
precompile.cc
precompile.h
print_python_deps.py
protoc_java.py
protoc_java.pydeps
redirect_stdout.py
rm.py
sample_arg_file.gn
sanitize-mac-build-log.sed
sanitize-mac-build-log.sh
sanitize-win-build-log.sed
sanitize-win-build-log.sh
shim_headers.gni
symlink.gni
symlink.py
timestamp.gni
tree_truth.sh
update-linux-sandbox.sh
vs_toolchain.py
whitespace_file.txt
write_buildflag_header.py
xcode_binaries.yaml
zip_helpers.py
zip_helpers_unittest.py
build_overrides
buildtools
cc
chrome
chromecast
chromeos
clank
codelabs
components
content
courgette
crypto
dbus
device
docs
extensions
fuchsia_web
gin
google_apis
google_update
gpu
headless
infra
internal
ios
ios_internal
ipc
media
mojo
native_client
native_client_sdk
net
pdf
ppapi
printing
remoting
rlz
sandbox
services
signing_keys
skia
sql
storage
styleguide
testing
third_party
tools
ui
url
v8
webkit
.clang-format
.clang-tidy
.clangd
.eslintrc.js
.git-blame-ignore-revs
.gitallowed
.gitattributes
.gitignore
.gitmodules
.gn
.mailmap
.rustfmt.toml
.vpython3
.yapfignore
ATL_OWNERS
AUTHORS
BUILD.gn
CODE_OF_CONDUCT.md
DEPS
DIR_METADATA
LICENSE
LICENSE.chromium_os
OWNERS
PRESUBMIT.py
PRESUBMIT_test.py
PRESUBMIT_test_mocks.py
README.md
WATCHLISTS
codereview.settings

Bug: 1364289 Change-Id: I559c3bee3c7d7ae191d3bbe58fef8e8a8ecb81cd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3931362 Commit-Queue: Daniel Cheng <dcheng@chromium.org> Reviewed-by: Egor Pasko <pasko@chromium.org> Cr-Commit-Position: refs/heads/main@{#1054166}
184 lines
6.5 KiB
Python
Executable File
184 lines
6.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# Copyright 2020 The Chromium Authors
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
"""Tests for java_cpp_features.py.
|
|
|
|
This test suite contains various tests for the C++ -> Java base::Feature
|
|
generator.
|
|
"""
|
|
|
|
import unittest
|
|
|
|
import java_cpp_features
|
|
from util import java_cpp_utils
|
|
|
|
|
|
class _TestFeaturesParser(unittest.TestCase):
|
|
def testParseComments(self):
|
|
test_data = """
|
|
/**
|
|
* This should be ignored as well.
|
|
*/
|
|
|
|
// Comment followed by a blank line.
|
|
|
|
// Comment followed by unrelated code.
|
|
int foo() { return 3; }
|
|
|
|
// Real comment. base::Feature intentionally split across two lines.
|
|
BASE_FEATURE(kSomeFeature, "SomeFeature",
|
|
base::FEATURE_DISABLED_BY_DEFAULT);
|
|
|
|
// Real comment that spans
|
|
// multiple lines.
|
|
BASE_FEATURE(kSomeOtherFeature, "SomeOtherFeature",
|
|
base::FEATURE_ENABLED_BY_DEFAULT);
|
|
|
|
// Comment followed by nothing.
|
|
""".split('\n')
|
|
feature_file_parser = java_cpp_utils.CppConstantParser(
|
|
java_cpp_features.FeatureParserDelegate(), test_data)
|
|
features = feature_file_parser.Parse()
|
|
self.assertEqual(2, len(features))
|
|
self.assertEqual('SOME_FEATURE', features[0].name)
|
|
self.assertEqual('"SomeFeature"', features[0].value)
|
|
self.assertEqual(1, len(features[0].comments.split('\n')))
|
|
self.assertEqual('SOME_OTHER_FEATURE', features[1].name)
|
|
self.assertEqual('"SomeOtherFeature"', features[1].value)
|
|
self.assertEqual(2, len(features[1].comments.split('\n')))
|
|
|
|
def testWhitespace(self):
|
|
test_data = """
|
|
// 1 line
|
|
BASE_FEATURE(kShort, "Short", base::FEATURE_DISABLED_BY_DEFAULT);
|
|
|
|
// 2 lines
|
|
BASE_FEATURE(kTwoLineFeatureA, "TwoLineFeatureA",
|
|
base::FEATURE_DISABLED_BY_DEFAULT);
|
|
BASE_FEATURE(kTwoLineFeatureB,
|
|
"TwoLineFeatureB", base::FEATURE_DISABLED_BY_DEFAULT);
|
|
|
|
// 3 lines
|
|
BASE_FEATURE(kFeatureWithAVeryLongNameThatWillHaveToWrap,
|
|
"FeatureWithAVeryLongNameThatWillHaveToWrap",
|
|
base::FEATURE_DISABLED_BY_DEFAULT);
|
|
""".split('\n')
|
|
feature_file_parser = java_cpp_utils.CppConstantParser(
|
|
java_cpp_features.FeatureParserDelegate(), test_data)
|
|
features = feature_file_parser.Parse()
|
|
self.assertEqual(4, len(features))
|
|
self.assertEqual('SHORT', features[0].name)
|
|
self.assertEqual('"Short"', features[0].value)
|
|
self.assertEqual('TWO_LINE_FEATURE_A', features[1].name)
|
|
self.assertEqual('"TwoLineFeatureA"', features[1].value)
|
|
self.assertEqual('TWO_LINE_FEATURE_B', features[2].name)
|
|
self.assertEqual('"TwoLineFeatureB"', features[2].value)
|
|
self.assertEqual('FEATURE_WITH_A_VERY_LONG_NAME_THAT_WILL_HAVE_TO_WRAP',
|
|
features[3].name)
|
|
self.assertEqual('"FeatureWithAVeryLongNameThatWillHaveToWrap"',
|
|
features[3].value)
|
|
|
|
def testCppSyntax(self):
|
|
test_data = """
|
|
// Mismatched name
|
|
BASE_FEATURE(kMismatchedFeature, "MismatchedName",
|
|
base::FEATURE_DISABLED_BY_DEFAULT);
|
|
|
|
namespace myfeature {
|
|
// In a namespace
|
|
BASE_FEATURE(kSomeFeature, "SomeFeature",
|
|
base::FEATURE_DISABLED_BY_DEFAULT);
|
|
}
|
|
|
|
// Build config-specific base::Feature
|
|
#if BUILDFLAG(IS_ANDROID)
|
|
BASE_FEATURE(kAndroidOnlyFeature, "AndroidOnlyFeature",
|
|
base::FEATURE_DISABLED_BY_DEFAULT);
|
|
#endif
|
|
|
|
// Value depends on build config
|
|
BASE_FEATURE(kMaybeEnabled, "MaybeEnabled",
|
|
#if BUILDFLAG(IS_ANDROID)
|
|
base::FEATURE_DISABLED_BY_DEFAULT
|
|
#else
|
|
base::FEATURE_ENABLED_BY_DEFAULT
|
|
#endif
|
|
);
|
|
""".split('\n')
|
|
feature_file_parser = java_cpp_utils.CppConstantParser(
|
|
java_cpp_features.FeatureParserDelegate(), test_data)
|
|
features = feature_file_parser.Parse()
|
|
self.assertEqual(4, len(features))
|
|
self.assertEqual('MISMATCHED_FEATURE', features[0].name)
|
|
self.assertEqual('"MismatchedName"', features[0].value)
|
|
self.assertEqual('SOME_FEATURE', features[1].name)
|
|
self.assertEqual('"SomeFeature"', features[1].value)
|
|
self.assertEqual('ANDROID_ONLY_FEATURE', features[2].name)
|
|
self.assertEqual('"AndroidOnlyFeature"', features[2].value)
|
|
self.assertEqual('MAYBE_ENABLED', features[3].name)
|
|
self.assertEqual('"MaybeEnabled"', features[3].value)
|
|
|
|
def testNotYetSupported(self):
|
|
# Negative test for cases we don't yet support, to ensure we don't misparse
|
|
# these until we intentionally add proper support.
|
|
test_data = """
|
|
// Not currently supported: name depends on C++ directive
|
|
BASE_FEATURE(kNameDependsOnOs,
|
|
#if BUILDFLAG(IS_ANDROID)
|
|
"MaybeName1",
|
|
#else
|
|
"MaybeName2",
|
|
#endif
|
|
base::FEATURE_DISABLED_BY_DEFAULT);
|
|
|
|
// Not currently supported: feature named with a constant instead of literal
|
|
BASE_FEATURE(kNamedAfterConstant, kNamedStringConstant,
|
|
base::FEATURE_DISABLED_BY_DEFAULT};
|
|
""".split('\n')
|
|
feature_file_parser = java_cpp_utils.CppConstantParser(
|
|
java_cpp_features.FeatureParserDelegate(), test_data)
|
|
features = feature_file_parser.Parse()
|
|
self.assertEqual(0, len(features))
|
|
|
|
def testTreatWebViewLikeOneWord(self):
|
|
test_data = """
|
|
BASE_FEATURE(kSomeWebViewFeature, "SomeWebViewFeature",
|
|
base::FEATURE_DISABLED_BY_DEFAULT);
|
|
BASE_FEATURE(kWebViewOtherFeature, "WebViewOtherFeature",
|
|
base::FEATURE_ENABLED_BY_DEFAULT);
|
|
BASE_FEATURE(kFeatureWithPluralWebViews,
|
|
"FeatureWithPluralWebViews",
|
|
base::FEATURE_ENABLED_BY_DEFAULT);
|
|
""".split('\n')
|
|
feature_file_parser = java_cpp_utils.CppConstantParser(
|
|
java_cpp_features.FeatureParserDelegate(), test_data)
|
|
features = feature_file_parser.Parse()
|
|
self.assertEqual('SOME_WEBVIEW_FEATURE', features[0].name)
|
|
self.assertEqual('"SomeWebViewFeature"', features[0].value)
|
|
self.assertEqual('WEBVIEW_OTHER_FEATURE', features[1].name)
|
|
self.assertEqual('"WebViewOtherFeature"', features[1].value)
|
|
self.assertEqual('FEATURE_WITH_PLURAL_WEBVIEWS', features[2].name)
|
|
self.assertEqual('"FeatureWithPluralWebViews"', features[2].value)
|
|
|
|
def testSpecialCharacters(self):
|
|
test_data = r"""
|
|
BASE_FEATURE(kFeatureWithEscapes, "Weird\tfeature\"name\n",
|
|
base::FEATURE_DISABLED_BY_DEFAULT);
|
|
BASE_FEATURE(kFeatureWithEscapes2,
|
|
"Weird\tfeature\"name\n",
|
|
base::FEATURE_ENABLED_BY_DEFAULT);
|
|
""".split('\n')
|
|
feature_file_parser = java_cpp_utils.CppConstantParser(
|
|
java_cpp_features.FeatureParserDelegate(), test_data)
|
|
features = feature_file_parser.Parse()
|
|
self.assertEqual('FEATURE_WITH_ESCAPES', features[0].name)
|
|
self.assertEqual(r'"Weird\tfeature\"name\n"', features[0].value)
|
|
self.assertEqual('FEATURE_WITH_ESCAPES2', features[1].name)
|
|
self.assertEqual(r'"Weird\tfeature\"name\n"', features[1].value)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|