@@ -151,7 +151,7 @@ impl TryFrom<Format> for Vec<Resource> {
151151 id : id. clone ( ) ,
152152 value : Translation :: Empty ,
153153 comment : item. comment . clone ( ) ,
154- status : EntryStatus :: Translated ,
154+ status : EntryStatus :: New ,
155155 custom : custom. clone ( ) ,
156156 } ) ;
157157 }
@@ -408,6 +408,63 @@ impl PluralVariation {
408408mod tests {
409409 use super :: * ;
410410
411+ fn format_with_translated_before_empty ( ) -> Format {
412+ for _ in 0 ..256 {
413+ let mut strings = HashMap :: new ( ) ;
414+ strings. insert (
415+ "translated_key" . to_string ( ) ,
416+ Item {
417+ localizations : {
418+ let mut localizations = HashMap :: new ( ) ;
419+ localizations. insert (
420+ "en" . to_string ( ) ,
421+ Localization :: from ( StringUnit :: new ( EntryStatus :: Translated , "Hello" ) ) ,
422+ ) ;
423+ localizations. insert (
424+ "fr" . to_string ( ) ,
425+ Localization :: from ( StringUnit :: new ( EntryStatus :: Translated , "Bonjour" ) ) ,
426+ ) ;
427+ localizations
428+ } ,
429+ comment : None ,
430+ extraction_state : None ,
431+ should_translate : Some ( true ) ,
432+ is_comment_auto_generated : None ,
433+ } ,
434+ ) ;
435+ strings. insert (
436+ "empty_key" . to_string ( ) ,
437+ Item {
438+ localizations : HashMap :: new ( ) ,
439+ comment : Some ( "Missing translation" . to_string ( ) ) ,
440+ extraction_state : None ,
441+ should_translate : Some ( true ) ,
442+ is_comment_auto_generated : None ,
443+ } ,
444+ ) ;
445+
446+ let order: Vec < & str > = strings. keys ( ) . map ( String :: as_str) . collect ( ) ;
447+ let translated_pos = order
448+ . iter ( )
449+ . position ( |key| * key == "translated_key" )
450+ . expect ( "translated key in map" ) ;
451+ let empty_pos = order
452+ . iter ( )
453+ . position ( |key| * key == "empty_key" )
454+ . expect ( "empty key in map" ) ;
455+
456+ if translated_pos < empty_pos {
457+ return Format {
458+ source_language : "en" . to_string ( ) ,
459+ version : "1.0" . to_string ( ) ,
460+ strings,
461+ } ;
462+ }
463+ }
464+
465+ panic ! ( "failed to build deterministic key order for xcstrings test" ) ;
466+ }
467+
411468 #[ test]
412469 fn test_ios_placeholder_conversion_in_writer ( ) {
413470 // Build resources that contain Android-style placeholders
@@ -470,4 +527,23 @@ mod tests {
470527 . contains( "%1$@" )
471528 ) ;
472529 }
530+
531+ #[ test]
532+ fn test_empty_item_is_marked_new_when_expanded_for_existing_languages ( ) {
533+ let format = format_with_translated_before_empty ( ) ;
534+ let resources = Vec :: < Resource > :: try_from ( format) . expect ( "resources from xcstrings" ) ;
535+ assert_eq ! ( resources. len( ) , 2 ) ;
536+
537+ for resource in resources {
538+ let empty_entry = resource
539+ . entries
540+ . iter ( )
541+ . find ( |entry| entry. id == "empty_key" )
542+ . expect ( "empty entry is generated for each known language" ) ;
543+
544+ assert_eq ! ( empty_entry. value, Translation :: Empty ) ;
545+ assert_eq ! ( empty_entry. status, EntryStatus :: New ) ;
546+ assert_eq ! ( empty_entry. comment. as_deref( ) , Some ( "Missing translation" ) ) ;
547+ }
548+ }
473549}
0 commit comments