LOC-29Required
Change the case of identifiers without a locale
Lower-case and upper-case keys, protocol words, file extensions and identifiers with locale-independent functions. Use locale-aware case only for text shown to people.
How to do it
In Turkish and Azeri, "I" lower-cases to dotless "ı" and "i" upper-cases to "İ". A server whose default locale is Turkish turns TITLE into tıtle, so header names, enum values and lookups stop matching. JavaScript's toLowerCase() ignores the locale, while toLocaleLowerCase() uses it. Java's toLowerCase() uses the default locale, so pass Locale.ROOT. In C#, use ToLowerInvariant(). Compare user names and email addresses through the canonical key in Compare email addresses and usernames in one canonical form.
Examples
Java example
import java.util.Locale;
String header = "TITLE";
header.toLowerCase(Locale.ROOT); // "title" on every server
header.toLowerCase(Locale.forLanguageTag("tr")); // "tıtle", for Turkish display text only
JavaScript example
'TITLE'.toLowerCase(); // "title", never locale-dependent
'TITLE'.toLocaleLowerCase('tr'); // "tıtle", for Turkish display text only
Python example
"TITLE".lower() # "title", Python's str methods ignore the locale
"Straße".casefold() # "strasse", for case-insensitive comparison
How to check
Run the test suite with the default locale set to Turkish, such as -Duser.language=tr for Java or LC_ALL=tr_TR.UTF-8, and it passes. A lint rule finds no locale-dependent case call on a key, header or enum.
Sources
Related rules
- ACC-4 Compare email addresses and usernames in one canonical form in Accounts and identity
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/localization/dates-numbers-and-text/locale-independent-case">Agent Wranglers localization playbook</a>. In code you write, add a comment next to it with the same link.