@@ -822,3 +822,168 @@ mod analyze_value_tests {
822822 assert_eq ! ( suggestions[ 0 ] . text, ".field" ) ;
823823 }
824824}
825+
826+ // ============================================================================
827+ // Nonsimple Field Name Quoting Tests
828+ // ============================================================================
829+
830+ #[ test]
831+ fn test_field_starting_with_digit_gets_quoted ( ) {
832+ let json: Value = serde_json:: from_str ( r#"{"1numeric_key": "value"}"# ) . unwrap ( ) ;
833+ let suggestions = ResultAnalyzer :: analyze_value ( & json, true , false ) ;
834+
835+ assert_eq ! ( suggestions. len( ) , 1 ) ;
836+ assert_eq ! ( suggestions[ 0 ] . text, r#"."1numeric_key""# ) ;
837+ }
838+
839+ #[ test]
840+ fn test_field_with_hyphen_gets_quoted ( ) {
841+ let json: Value = serde_json:: from_str ( r#"{"my-field": "value"}"# ) . unwrap ( ) ;
842+ let suggestions = ResultAnalyzer :: analyze_value ( & json, true , false ) ;
843+
844+ assert_eq ! ( suggestions. len( ) , 1 ) ;
845+ assert_eq ! ( suggestions[ 0 ] . text, r#"."my-field""# ) ;
846+ }
847+
848+ #[ test]
849+ fn test_valid_field_name_not_quoted ( ) {
850+ let json: Value = serde_json:: from_str ( r#"{"simple_key": "value"}"# ) . unwrap ( ) ;
851+ let suggestions = ResultAnalyzer :: analyze_value ( & json, true , false ) ;
852+
853+ assert_eq ! ( suggestions. len( ) , 1 ) ;
854+ assert_eq ! ( suggestions[ 0 ] . text, ".simple_key" ) ;
855+ }
856+
857+ #[ test]
858+ fn test_multiple_fields_with_mixed_identifier_types ( ) {
859+ let json: Value =
860+ serde_json:: from_str ( r#"{"simple_key": 1, "1numeric_key": 2, "hyphen-key": 3}"# ) . unwrap ( ) ;
861+ let suggestions = ResultAnalyzer :: analyze_value ( & json, true , false ) ;
862+
863+ assert_eq ! ( suggestions. len( ) , 3 ) ;
864+ let suggestion_texts: Vec < _ > = suggestions. iter ( ) . map ( |s| s. text . as_str ( ) ) . collect ( ) ;
865+ assert ! ( suggestion_texts. contains( & ".simple_key" ) ) ;
866+ assert ! ( suggestion_texts. contains( & r#"."1numeric_key""# ) ) ;
867+ assert ! ( suggestion_texts. contains( & r#"."hyphen-key""# ) ) ;
868+ }
869+
870+ #[ test]
871+ fn test_array_of_objects_with_nonsimple_field_names ( ) {
872+ let json: Value = serde_json:: from_str (
873+ r#"[{"1numeric_key": "value1", "simple_key": "value2"}, {"1numeric_key": "value3", "simple_key": "value4"}]"# ,
874+ )
875+ . unwrap ( ) ;
876+ let suggestions = ResultAnalyzer :: analyze_value ( & json, true , false ) ;
877+
878+ assert_eq ! ( suggestions. len( ) , 3 ) ; // .[], .[].1numeric_key, .[].simple_key
879+ let suggestion_texts: Vec < _ > = suggestions. iter ( ) . map ( |s| s. text . as_str ( ) ) . collect ( ) ;
880+ assert ! ( suggestion_texts. contains( & ".[]" ) ) ;
881+ assert ! ( suggestion_texts. contains( & r#".[]."1numeric_key""# ) ) ;
882+ assert ! ( suggestion_texts. contains( & ".[].simple_key" ) ) ;
883+ }
884+
885+ #[ test]
886+ fn test_no_leading_dot_with_nonsimple_field ( ) {
887+ let json: Value = serde_json:: from_str ( r#"{"1numeric_key": "value"}"# ) . unwrap ( ) ;
888+ let suggestions = ResultAnalyzer :: analyze_value ( & json, false , false ) ;
889+
890+ assert_eq ! ( suggestions. len( ) , 1 ) ;
891+ assert_eq ! ( suggestions[ 0 ] . text, r#""1numeric_key""# ) ;
892+ }
893+
894+ // ============================================================================
895+ // Complex Nested Scenarios Tests
896+ // ============================================================================
897+
898+ #[ test]
899+ fn test_nested_array_name_quoting_across_levels ( ) {
900+ // Scenario: ."hyphen-array"[]."nested-items"[] with nested array names
901+ let json: Value = serde_json:: from_str (
902+ r#"{
903+ "hyphen-array": [
904+ {
905+ "nested-items": [
906+ {"simple_key": "value"}
907+ ]
908+ }
909+ ]
910+ }"# ,
911+ )
912+ . unwrap ( ) ;
913+
914+ let top_level = ResultAnalyzer :: analyze_value ( & json, true , false ) ;
915+ assert ! ( top_level. iter( ) . any( |s| s. text == r#"."hyphen-array""# ) ) ;
916+ assert ! ( !top_level. iter( ) . any( |s| s. text == ".hyphen-array" ) ) ;
917+
918+ let outer_array = json
919+ . get ( "hyphen-array" )
920+ . and_then ( Value :: as_array)
921+ . expect ( "outer array should exist" ) ;
922+ let outer_obj = outer_array
923+ . first ( )
924+ . and_then ( Value :: as_object)
925+ . expect ( "outer array should contain object" ) ;
926+ let outer_obj_value = Value :: Object ( outer_obj. clone ( ) ) ;
927+ let nested_level = ResultAnalyzer :: analyze_value ( & outer_obj_value, true , false ) ;
928+ assert ! ( nested_level. iter( ) . any( |s| s. text == r#"."nested-items""# ) ) ;
929+ assert ! ( !nested_level. iter( ) . any( |s| s. text == ".nested-items" ) ) ;
930+ }
931+
932+ #[ test]
933+ fn test_nested_field_quoting_with_iteration ( ) {
934+ // Scenario: .outer[]."inner-array"[]."hyphen-key" and .[]."1numeric_key"
935+ let json: Value = serde_json:: from_str (
936+ r#"{
937+ "outer": [
938+ {
939+ "inner-array": [
940+ {"hyphen-key": "v1", "1numeric_key": "v2", "simple_key": "v3"}
941+ ]
942+ }
943+ ]
944+ }"# ,
945+ )
946+ . unwrap ( ) ;
947+
948+ let outer_array = json
949+ . get ( "outer" )
950+ . and_then ( Value :: as_array)
951+ . expect ( "outer array should exist" ) ;
952+ let outer_obj = outer_array
953+ . first ( )
954+ . and_then ( Value :: as_object)
955+ . expect ( "outer array should contain object" ) ;
956+ let outer_obj_value = Value :: Object ( outer_obj. clone ( ) ) ;
957+ let outer_suggestions = ResultAnalyzer :: analyze_value ( & outer_obj_value, true , false ) ;
958+ assert ! (
959+ outer_suggestions
960+ . iter( )
961+ . any( |s| s. text == r#"."inner-array""# )
962+ ) ;
963+
964+ let inner_array = outer_obj_value
965+ . get ( "inner-array" )
966+ . and_then ( Value :: as_array)
967+ . expect ( "inner array should exist" ) ;
968+ let inner_array_value = Value :: Array ( inner_array. clone ( ) ) ;
969+ let inner_suggestions = ResultAnalyzer :: analyze_value ( & inner_array_value, true , false ) ;
970+
971+ assert ! ( inner_suggestions. iter( ) . any( |s| s. text == ".[]" ) ) ;
972+ assert ! (
973+ inner_suggestions
974+ . iter( )
975+ . any( |s| s. text == r#".[]."hyphen-key""# )
976+ ) ;
977+ assert ! (
978+ inner_suggestions
979+ . iter( )
980+ . any( |s| s. text == r#".[]."1numeric_key""# )
981+ ) ;
982+ assert ! ( inner_suggestions. iter( ) . any( |s| s. text == ".[].simple_key" ) ) ;
983+ assert ! ( !inner_suggestions. iter( ) . any( |s| s. text == ".[].hyphen-key" ) ) ;
984+ assert ! (
985+ !inner_suggestions
986+ . iter( )
987+ . any( |s| s. text == ".[].1numeric_key" )
988+ ) ;
989+ }
0 commit comments