diff --git a/.github/workflows/intl4x.yml b/.github/workflows/intl4x.yml index d8c34d4eb..e29594d51 100644 --- a/.github/workflows/intl4x.yml +++ b/.github/workflows/intl4x.yml @@ -6,6 +6,7 @@ permissions: on: pull_request: branches: [main] + types: [opened, synchronize, reopened, labeled, unlabeled] paths: - ".github/workflows/intl4x.yml" - "pkgs/intl4x/**" @@ -293,21 +294,21 @@ jobs: run: | rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/linux_x64 --os linux --architecture x64 --compile_type dynamic --cargo_features collator,datetime,list,decimal,plurals,experimental,compiled_data + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/linux_x64 --os linux --architecture x64 --compile_type dynamic --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental,compiled_data - name: Build Mac if: matrix.os == 'macos-latest' run: | rustup component add rust-src --toolchain nightly-aarch64-apple-darwin - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/macos_arm64 --os macos --architecture arm64 --compile_type dynamic --cargo_features collator,datetime,list,decimal,plurals,experimental,compiled_data + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/macos_arm64 --os macos --architecture arm64 --compile_type dynamic --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental,compiled_data - name: Build Windows if: matrix.os == 'windows-latest' run: | rustup component add rust-src --toolchain nightly-x86_64-pc-windows-msvc - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/windows_x64 --os windows --architecture x64 --compile_type dynamic --cargo_features collator,datetime,list,decimal,plurals,experimental,compiled_data + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/windows_x64 --os windows --architecture x64 --compile_type dynamic --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental,compiled_data - name: Run `dart pub get` run: | diff --git a/.github/workflows/intl4x_artifacts.yml b/.github/workflows/intl4x_artifacts.yml index 8e7d61005..9947c7ee5 100644 --- a/.github/workflows/intl4x_artifacts.yml +++ b/.github/workflows/intl4x_artifacts.yml @@ -73,14 +73,14 @@ jobs: mkdir submodules/icu4x/bin - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/android_arm_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os android --architecture arm --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,experimental${{ env.DATA }} - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/android_arm64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os android --architecture arm64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,experimental${{ env.DATA }} - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/android_ia32_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os android --architecture ia32 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,experimental${{ env.DATA }} - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/android_x64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os android --architecture x64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,experimental${{ env.DATA }} - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/linux_arm_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os linux --architecture arm --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,experimental${{ env.DATA }} - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/linux_arm64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os linux --architecture arm64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,experimental${{ env.DATA }} - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/linux_riscv64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os linux --architecture riscv64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,experimental${{ env.DATA }} - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/linux_x64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os linux --architecture x64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,experimental${{ env.DATA }} + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/android_arm_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os android --architecture arm --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental${{ env.DATA }} + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/android_arm64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os android --architecture arm64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental${{ env.DATA }} + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/android_ia32_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os android --architecture ia32 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental${{ env.DATA }} + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/android_x64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os android --architecture x64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental${{ env.DATA }} + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/linux_arm_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os linux --architecture arm --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental${{ env.DATA }} + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/linux_arm64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os linux --architecture arm64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental${{ env.DATA }} + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/linux_riscv64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os linux --architecture riscv64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental${{ env.DATA }} + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/linux_x64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os linux --architecture x64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental${{ env.DATA }} - name: Build Linux data if: matrix.os == 'ubuntu-latest' && matrix.compiletype == 'static' && matrix.include_data == false @@ -111,10 +111,10 @@ jobs: mkdir submodules/icu4x/bin - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/ios_arm64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os ios --architecture arm64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,experimental${{ env.DATA }} - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/ios_x64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os ios --architecture x64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,experimental${{ env.DATA }} - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/macos_arm64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os macos --architecture arm64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,experimental${{ env.DATA }} - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/macos_x64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os macos --architecture x64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,experimental${{ env.DATA }} + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/ios_arm64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os ios --architecture arm64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental${{ env.DATA }} + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/ios_x64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os ios --architecture x64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental${{ env.DATA }} + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/macos_arm64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os macos --architecture arm64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental${{ env.DATA }} + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/macos_x64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os macos --architecture x64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental${{ env.DATA }} - name: Build Mac data if: matrix.os == 'macos-latest' && matrix.compiletype == 'static' && matrix.include_data == false @@ -140,9 +140,9 @@ jobs: mkdir submodules/icu4x/bin - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/windows_arm64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os windows --architecture arm64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,experimental${{ env.DATA }} - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/windows_ia32_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os windows --architecture ia32 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,experimental${{ env.DATA }} - dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/windows_x64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os windows --architecture x64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,experimental${{ env.DATA }} + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/windows_arm64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os windows --architecture arm64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental${{ env.DATA }} + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/windows_ia32_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os windows --architecture ia32 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental${{ env.DATA }} + dart pkgs/intl4x/lib/src/hook_helpers/build_libs.g.dart --working_directory submodules/icu4x --file submodules/icu4x/bin/windows_x64_${{ matrix.compiletype }}${{ env.FILENAME_SUFFIX }} --os windows --architecture x64 --compile_type ${{ matrix.compiletype }} --cargo_features collator,datetime,list,decimal,plurals,casemap,experimental${{ env.DATA }} - name: Build Windows data if: matrix.os == 'windows-latest' && matrix.compiletype == 'static' && matrix.include_data == false diff --git a/pkgs/intl4x/CHANGELOG.md b/pkgs/intl4x/CHANGELOG.md index 6ab96d250..6065f6b28 100644 --- a/pkgs/intl4x/CHANGELOG.md +++ b/pkgs/intl4x/CHANGELOG.md @@ -1,7 +1,11 @@ +## 0.12.2-wip + +- Add lower- and uppercasing. + ## 0.12.1 - Use new artifacts from `intl4x-icu-v.0.12.0-artifacts`. - + ## 0.12.0 - Update to ICU4X 2.0. diff --git a/pkgs/intl4x/hook/build.dart b/pkgs/intl4x/hook/build.dart index 08b1a4166..b137cad1d 100644 --- a/pkgs/intl4x/hook/build.dart +++ b/pkgs/intl4x/hook/build.dart @@ -215,7 +215,7 @@ final class CheckoutMode extends BuildMode { 'plurals', 'buffer_provider', 'experimental', - 'default_components', + 'casemap', 'compiled_data', ], ); diff --git a/pkgs/intl4x/lib/case_mapping.dart b/pkgs/intl4x/lib/case_mapping.dart new file mode 100644 index 000000000..9853c6ba1 --- /dev/null +++ b/pkgs/intl4x/lib/case_mapping.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'intl4x.dart'; + +export 'src/case_mapping/case_mapping.dart'; +export 'src/locale/locale.dart'; + +extension CaseMappingWithIntl4X on String { + String toLocaleLowerCase(Locale locale) => + Intl(locale: locale).caseMapping.toLowerCase(this); + String toLocaleUpperCase(Locale locale) => + Intl(locale: locale).caseMapping.toUpperCase(this); +} diff --git a/pkgs/intl4x/lib/intl4x.dart b/pkgs/intl4x/lib/intl4x.dart index 106c83dde..c3e905888 100644 --- a/pkgs/intl4x/lib/intl4x.dart +++ b/pkgs/intl4x/lib/intl4x.dart @@ -2,9 +2,11 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'case_mapping.dart'; import 'collation.dart'; import 'display_names.dart'; import 'number_format.dart'; +import 'src/case_mapping/case_mapping_impl.dart'; import 'src/collation/collation.dart'; import 'src/collation/collation_impl.dart'; import 'src/datetime_format/datetime_format.dart'; @@ -18,7 +20,6 @@ import 'src/find_locale.dart'; import 'src/list_format/list_format.dart'; import 'src/list_format/list_format_impl.dart'; import 'src/list_format/list_format_options.dart'; -import 'src/locale/locale.dart'; import 'src/number_format/number_format.dart'; import 'src/number_format/number_format_impl.dart'; import 'src/plural_rules/plural_rules.dart'; @@ -88,6 +89,9 @@ class Intl { ), ); + CaseMapping get caseMapping => + CaseMapping(CaseMappingImpl.build(locale, localeMatcher, ecmaPolicy)); + /// Construct an [Intl] instance providing the current [locale] and the /// [ecmaPolicy] defining which locales should fall back to the browser /// provided functions. diff --git a/pkgs/intl4x/lib/src/case_mapping/case_mapping.dart b/pkgs/intl4x/lib/src/case_mapping/case_mapping.dart new file mode 100644 index 000000000..3f818fcb4 --- /dev/null +++ b/pkgs/intl4x/lib/src/case_mapping/case_mapping.dart @@ -0,0 +1,33 @@ +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import '../test_checker.dart'; +import 'case_mapping_impl.dart'; + +/// A locale-sensitive case mapper for transforming strings. +/// +/// This class provides methods to convert strings to lowercase or uppercase +/// based on the current locale. During testing, the input is returned +/// unchanged. +class CaseMapping { + final CaseMappingImpl _caseMappingImpl; + + const CaseMapping(this._caseMappingImpl); + + String toLowerCase(String input) { + if (isInTest) { + return input; + } else { + return _caseMappingImpl.toLowerCase(input); + } + } + + String toUpperCase(String input) { + if (isInTest) { + return input; + } else { + return _caseMappingImpl.toUpperCase(input); + } + } +} diff --git a/pkgs/intl4x/lib/src/case_mapping/case_mapping_4x.dart b/pkgs/intl4x/lib/src/case_mapping/case_mapping_4x.dart new file mode 100644 index 000000000..fc17a560f --- /dev/null +++ b/pkgs/intl4x/lib/src/case_mapping/case_mapping_4x.dart @@ -0,0 +1,26 @@ +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import '../bindings/lib.g.dart' as icu; +import '../locale/locale.dart'; +import '../locale/locale_4x.dart'; +import 'case_mapping_impl.dart'; + +CaseMappingImpl getCaseMapping4X(Locale locale, Null _) => + CaseMapping4X(locale as Locale4x); + +class CaseMapping4X extends CaseMappingImpl { + final icu.CaseMapper _caseMapper; + final Locale4x _locale; + + CaseMapping4X(this._locale) : _caseMapper = icu.CaseMapper(), super(_locale); + + @override + String toLowerCase(String input) => + _caseMapper.lowercase(input, _locale.get4X); + + @override + String toUpperCase(String input) => + _caseMapper.uppercase(input, _locale.get4X); +} diff --git a/pkgs/intl4x/lib/src/case_mapping/case_mapping_ecma.dart b/pkgs/intl4x/lib/src/case_mapping/case_mapping_ecma.dart new file mode 100644 index 000000000..75c15160e --- /dev/null +++ b/pkgs/intl4x/lib/src/case_mapping/case_mapping_ecma.dart @@ -0,0 +1,32 @@ +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:js_interop'; + +import '../locale/locale.dart'; +import '../options.dart'; +import 'case_mapping_impl.dart'; + +CaseMappingImpl? getCaseMappingECMA(Locale locale, Null _, LocaleMatcher _) => + _CaseMappingECMA.tryToBuild(locale); + +extension on JSString { + @JS('String.toLocaleUpperCase') + external String toLocaleUpperCase(String locale); + @JS('String.toLocaleLowerCase') + external String toLocaleLowerCase(String locale); +} + +class _CaseMappingECMA extends CaseMappingImpl { + _CaseMappingECMA(super.locale); + + static CaseMappingImpl? tryToBuild(Locale locale) => _CaseMappingECMA(locale); + @override + String toUpperCase(String input) => + input.toJS.toLocaleUpperCase(locale.toLanguageTag()); + + @override + String toLowerCase(String input) => + input.toJS.toLocaleLowerCase(locale.toLanguageTag()); +} diff --git a/pkgs/intl4x/lib/src/case_mapping/case_mapping_impl.dart b/pkgs/intl4x/lib/src/case_mapping/case_mapping_impl.dart new file mode 100644 index 000000000..e62ea818d --- /dev/null +++ b/pkgs/intl4x/lib/src/case_mapping/case_mapping_impl.dart @@ -0,0 +1,33 @@ +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import '../../ecma_policy.dart'; +import '../ecma/ecma_policy.dart'; +import '../locale/locale.dart'; +import '../options.dart'; +import '../utils.dart'; +import 'case_mapping_stub.dart' if (dart.library.js) 'case_mapping_ecma.dart'; +import 'case_mapping_stub_4x.dart' if (dart.library.io) 'case_mapping_4x.dart'; + +abstract class CaseMappingImpl { + final Locale locale; + + CaseMappingImpl(this.locale); + + String toLowerCase(String input); + String toUpperCase(String input); + + static CaseMappingImpl build( + Locale locales, + LocaleMatcher localeMatcher, + EcmaPolicy ecmaPolicy, + ) => buildFormatter( + locales, + null, + localeMatcher, + ecmaPolicy, + getCaseMappingECMA, + getCaseMapping4X, + ); +} diff --git a/pkgs/intl4x/lib/src/case_mapping/case_mapping_stub.dart b/pkgs/intl4x/lib/src/case_mapping/case_mapping_stub.dart new file mode 100644 index 000000000..ac7a883e8 --- /dev/null +++ b/pkgs/intl4x/lib/src/case_mapping/case_mapping_stub.dart @@ -0,0 +1,10 @@ +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import '../locale/locale.dart'; +import '../options.dart'; +import 'case_mapping_impl.dart'; + +CaseMappingImpl? getCaseMappingECMA(Locale locale, Null _, LocaleMatcher _) => + throw UnimplementedError('Cannot use ECMA outside of web environments.'); diff --git a/pkgs/intl4x/lib/src/case_mapping/case_mapping_stub_4x.dart b/pkgs/intl4x/lib/src/case_mapping/case_mapping_stub_4x.dart new file mode 100644 index 000000000..38d5f42ab --- /dev/null +++ b/pkgs/intl4x/lib/src/case_mapping/case_mapping_stub_4x.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import '../locale/locale.dart'; +import 'case_mapping_impl.dart'; + +CaseMappingImpl getCaseMapping4X(Locale locale, Null _) => + throw UnimplementedError('Cannot use ICU4X in web environments.'); diff --git a/pkgs/intl4x/pubspec.yaml b/pkgs/intl4x/pubspec.yaml index 7f314c1f4..aa2c39f3d 100644 --- a/pkgs/intl4x/pubspec.yaml +++ b/pkgs/intl4x/pubspec.yaml @@ -1,7 +1,7 @@ name: intl4x description: >- A lightweight modular library for internationalization (i18n) functionality. -version: 0.12.1 +version: 0.12.2-wip repository: https://github.com/dart-lang/i18n/tree/main/pkgs/intl4x issue_tracker: https://github.com/dart-lang/i18n/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aintl4x diff --git a/pkgs/intl4x/test/case_mapping_test.dart b/pkgs/intl4x/test/case_mapping_test.dart new file mode 100644 index 000000000..1dc6c41b2 --- /dev/null +++ b/pkgs/intl4x/test/case_mapping_test.dart @@ -0,0 +1,56 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:intl4x/case_mapping.dart'; +import 'package:test/test.dart'; + +import 'utils.dart'; + +void main() { + testWithFormatting('test name', () { + final enUS = Locale.parse('en-US'); + final trTR = Locale.parse('tr-TR'); + final ltLT = Locale.parse('lt-LT'); + + expect('İstanbul'.toLocaleLowerCase(enUS), 'i̇stanbul'); + expect('İstanbul'.toLocaleLowerCase(trTR), 'istanbul'); + expect('ALPHABET'.toLocaleLowerCase(enUS), 'alphabet'); + + expect('\u0130'.toLocaleLowerCase(Locale.parse('tr')), 'i'); + expect('\u0130'.toLocaleLowerCase(enUS), isNot('i')); + + final locales = [ + 'tr', + 'TR', + 'tr-TR', + 'tr-u-co-search', + 'tr-x-turkish', + ].map(Locale.parse); + for (final locale in locales) { + expect('\u0130'.toLocaleLowerCase(locale), 'i'); + } + + // --- Lithuanian Testing --- + // Here, 'I' should lowercase to 'i' and 'i' should uppercase to 'I'. + // The dotless 'i' (U+0131) and dotted 'I' (U+0130) are not typically used + // in standard Lithuanian orthography in the same way as Turkish. + // So, we expect standard Unicode casing behavior. + + expect('Lietuva'.toLocaleLowerCase(ltLT), 'lietuva'); + expect('lietuva'.toLocaleUpperCase(ltLT), 'LIETUVA'); + + // Test a common character that might have locale-specific casing rules + // in other languages but should be standard in Lithuanian. + expect('Ė'.toLocaleLowerCase(ltLT), 'ė'); // Ė (U+0116) to ė (U+0117) + expect('ė'.toLocaleUpperCase(ltLT), 'Ė'); + + // Ensure that Turkish-specific behavior does NOT apply to Lithuanian + expect( + '\u0130'.toLocaleLowerCase(ltLT), + '\u0130'.toLocaleLowerCase(enUS), + ); // Dotted I should behave like in English + expect('I'.toLocaleLowerCase(ltLT), 'i'); // Regular I to i + expect('i'.toLocaleUpperCase(ltLT), 'I'); // Regular i to I + }); +}