@@ -217,6 +217,32 @@ def test_bash_reports_missing_utf8_locale_for_unicode_only(
217217 assert not (repo / "specs" ).exists ()
218218
219219
220+ @requires_bash
221+ @pytest .mark .parametrize ("locale_name" , ["C" , "POSIX" ])
222+ def test_bash_respects_explicit_non_utf8_lc_all (repo : Path , locale_name : str ) -> None :
223+ env = clean_env ()
224+ env ["LC_ALL" ] = locale_name
225+ env ["LANG" ] = "C.UTF-8"
226+
227+ ascii_result = run (
228+ bash_cmd (repo , SCRIPT , "--json" , "--dry-run" , "Add user authentication" ),
229+ repo ,
230+ env ,
231+ )
232+ assert ascii_result .returncode == 0 , ascii_result .stderr
233+ assert json_stdout (ascii_result )["BRANCH_NAME" ] == "001-user-authentication"
234+
235+ for args in (("添加用户" ,), ("--short-name" , "用户" , "Add users" )):
236+ unicode_result = run (
237+ bash_cmd (repo , SCRIPT , "--json" , "--dry-run" , * args ), repo , env
238+ )
239+ assert unicode_result .returncode == 1
240+ assert unicode_result .stdout == ""
241+ assert "A UTF-8 locale is required" in unicode_result .stderr
242+ assert "LC_ALL" in unicode_result .stderr
243+ assert not (repo / "specs" ).exists ()
244+
245+
220246@requires_bash
221247def test_bash_requires_python_only_for_unicode_names (
222248 repo : Path , tmp_path : Path
@@ -381,6 +407,54 @@ def test_python_branch_name_generation_matches_bash(
381407 assert json_stdout (py ) == json_stdout (bash )
382408
383409
410+ @requires_bash
411+ @pytest .mark .parametrize (
412+ ("description" , "expected" ),
413+ [("ſet account" , "001-ſet-account" ), ("Set account" , "001-account" )],
414+ )
415+ def test_bash_stop_words_match_only_ascii_words (
416+ repo : Path , description : str , expected : str
417+ ) -> None :
418+ bash = run (bash_cmd (repo , SCRIPT , "--json" , "--dry-run" , description ), repo )
419+ py = run (py_cmd (repo , SCRIPT , "--json" , "--dry-run" , description ), repo )
420+
421+ assert bash .returncode == py .returncode == 0
422+ assert json_stdout (bash ) == json_stdout (py )
423+ assert json_stdout (bash )["BRANCH_NAME" ] == expected
424+
425+
426+ @requires_bash
427+ def test_bash_stop_words_ignore_locale_case_folding (repo : Path , tmp_path : Path ) -> None :
428+ real_grep = shutil .which ("grep" )
429+ assert real_grep is not None
430+ shim_dir = tmp_path / "bin"
431+ shim_dir .mkdir ()
432+ grep_shim = shim_dir / "grep"
433+ grep_cmd = shlex .quote (_bash_posix_path (Path (real_grep )))
434+ grep_shim .write_text (
435+ "#!/bin/sh\n "
436+ 'if [ "$1" = "-qiE" ]; then\n '
437+ " IFS= read -r word\n "
438+ ' [ "$word" = "ſet" ] && exit 0\n '
439+ f' printf "%s\\ n" "$word" | { grep_cmd } "$@"\n '
440+ " exit $?\n "
441+ "fi\n "
442+ f'exec { grep_cmd } "$@"\n ' ,
443+ encoding = "utf-8" ,
444+ newline = "\n " ,
445+ )
446+ grep_shim .chmod (0o755 )
447+ env = clean_env ()
448+ env ["PATH" ] = f"{ shim_dir } { os .pathsep } { env ['PATH' ]} "
449+
450+ bash = run (bash_cmd (repo , SCRIPT , "--json" , "--dry-run" , "ſet account" ), repo , env )
451+ py = run (py_cmd (repo , SCRIPT , "--json" , "--dry-run" , "ſet account" ), repo , env )
452+
453+ assert bash .returncode == py .returncode == 0
454+ assert json_stdout (bash ) == json_stdout (py )
455+ assert json_stdout (bash )["BRANCH_NAME" ] == "001-ſet-account"
456+
457+
384458@requires_bash
385459@pytest .mark .skipif (not HAS_POWERSHELL , reason = "no PowerShell available" )
386460@pytest .mark .parametrize (
@@ -1489,7 +1563,8 @@ def test_no_ascii_word_description_matches_across_twins(
14891563 ps_repo = _setup_repo (tmp_path , "s" )
14901564
14911565 env = clean_env ()
1492- env ["LC_ALL" ] = env ["LANG" ] = "C"
1566+ env .pop ("LC_ALL" , None )
1567+ env ["LANG" ] = "C"
14931568 bash = run (
14941569 bash_cmd (bash_repo , SCRIPT , "--json" , "--dry-run" , description ), bash_repo , env
14951570 )
0 commit comments