@@ -53,4 +53,153 @@ describe("getObjectValue", () => {
5353 expect ( getObjectValue ( obj , "a" ) ) . toBeUndefined ( ) ;
5454 expect ( getObjectValue ( obj , "a" , 2 ) ) . toBe ( 2 ) ;
5555 } ) ;
56+
57+ describe ( "dot notation - nested access" , ( ) => {
58+ const testObject = {
59+ config : {
60+ api : {
61+ endpoints : {
62+ auth : "/api/auth" ,
63+ users : "/api/users" ,
64+ } ,
65+ } ,
66+ } ,
67+ user : {
68+ metadata : undefined ,
69+ preferences : null ,
70+ profile : {
71+ personal : {
72+ address : {
73+ city : "Paris" ,
74+ coordinates : {
75+ lat : 48.8566 ,
76+ lng : 2.3522 ,
77+ } ,
78+ country : "France" ,
79+ street : "123 Main St" ,
80+ } ,
81+ age : 30 ,
82+ name : "John Doe" ,
83+ } ,
84+ settings : {
85+ notifications : {
86+ email : true ,
87+ preferences : {
88+ marketing : false ,
89+ security : {
90+ loginAlerts : true ,
91+ passwordChanges : true ,
92+ } ,
93+ updates : true ,
94+ } ,
95+ push : false ,
96+ } ,
97+ theme : "dark" ,
98+ } ,
99+ } ,
100+ } ,
101+ } ;
102+
103+ it ( "accesses nested properties at different depths" , ( ) => {
104+ // Level 1
105+ expect ( getObjectValue ( testObject , "user" ) ) . toBeDefined ( ) ;
106+ expect ( getObjectValue ( testObject , "config" ) ) . toBeDefined ( ) ;
107+
108+ // Level 2
109+ expect ( getObjectValue ( testObject , "user.profile" ) ) . toBeDefined ( ) ;
110+ expect ( getObjectValue ( testObject , "config.api" ) ) . toBeDefined ( ) ;
111+
112+ // Level 3
113+ expect ( getObjectValue ( testObject , "user.profile.settings" ) ) . toBeDefined ( ) ;
114+ expect ( getObjectValue ( testObject , "user.profile.personal" ) ) . toBeDefined ( ) ;
115+ expect ( getObjectValue ( testObject , "config.api.endpoints" ) ) . toBeDefined ( ) ;
116+
117+ // Level 4
118+ expect ( getObjectValue ( testObject , "user.profile.settings.theme" ) ) . toBe ( "dark" ) ;
119+ expect ( getObjectValue ( testObject , "user.profile.personal.name" ) ) . toBe ( "John Doe" ) ;
120+ expect ( getObjectValue ( testObject , "user.profile.personal.age" ) ) . toBe ( 30 ) ;
121+ expect ( getObjectValue ( testObject , "config.api.endpoints.users" ) ) . toBe ( "/api/users" ) ;
122+
123+ // Level 5
124+ expect ( getObjectValue ( testObject , "user.profile.settings.notifications.email" ) ) . toBe ( true ) ;
125+ expect ( getObjectValue ( testObject , "user.profile.settings.notifications.push" ) ) . toBe ( false ) ;
126+ expect ( getObjectValue ( testObject , "user.profile.personal.address.street" ) ) . toBe ( "123 Main St" ) ;
127+ expect ( getObjectValue ( testObject , "user.profile.personal.address.city" ) ) . toBe ( "Paris" ) ;
128+
129+ // Level 6
130+ expect ( getObjectValue ( testObject , "user.profile.settings.notifications.preferences.marketing" ) ) . toBe ( false ) ;
131+ expect ( getObjectValue ( testObject , "user.profile.settings.notifications.preferences.updates" ) ) . toBe ( true ) ;
132+ expect ( getObjectValue ( testObject , "user.profile.personal.address.coordinates.lat" ) ) . toBe ( 48.8566 ) ;
133+ expect ( getObjectValue ( testObject , "user.profile.personal.address.coordinates.lng" ) ) . toBe ( 2.3522 ) ;
134+
135+ // Level 7
136+ expect ( getObjectValue ( testObject , "user.profile.settings.notifications.preferences.security.loginAlerts" ) ) . toBe ( true ) ;
137+ expect ( getObjectValue ( testObject , "user.profile.settings.notifications.preferences.security.passwordChanges" ) ) . toBe ( true ) ;
138+ } ) ;
139+
140+ it ( "returns undefined for non-existent nested paths" , ( ) => {
141+ expect ( getObjectValue ( testObject , "user.profile.settings.nonExistent" ) ) . toBeUndefined ( ) ;
142+ expect ( getObjectValue ( testObject , "user.profile.settings.theme.color" ) ) . toBeUndefined ( ) ;
143+ expect ( getObjectValue ( testObject , "user.nonExistent.property" ) ) . toBeUndefined ( ) ;
144+ expect ( getObjectValue ( testObject , "config.api.endpoints.nonExistent" ) ) . toBeUndefined ( ) ;
145+ expect ( getObjectValue ( testObject , "user.profile.personal.address.coordinates.elevation" ) ) . toBeUndefined ( ) ;
146+ } ) ;
147+
148+ it ( "returns default values for non-existent nested paths" , ( ) => {
149+ expect ( getObjectValue ( testObject , "user.profile.settings.language" , "en" ) ) . toBe ( "en" ) ;
150+ expect ( getObjectValue ( testObject , "user.profile.personal.phone" , "not provided" ) ) . toBe ( "not provided" ) ;
151+ expect ( getObjectValue ( testObject , "config.api.timeout" , 5000 ) ) . toBe ( 5000 ) ;
152+ expect ( getObjectValue ( testObject , "user.profile.personal.address.zipcode" , "75001" ) ) . toBe ( "75001" ) ;
153+ } ) ;
154+
155+ it ( "handles null and undefined values in nested paths" , ( ) => {
156+ expect ( getObjectValue ( testObject , "user.preferences" ) ) . toBeNull ( ) ;
157+ expect ( getObjectValue ( testObject , "user.preferences" , "default" ) ) . toBe ( "default" ) ;
158+ expect ( getObjectValue ( testObject , "user.preferences.something" , "fallback" ) ) . toBe ( "fallback" ) ;
159+
160+ expect ( getObjectValue ( testObject , "user.metadata" ) ) . toBeUndefined ( ) ;
161+ expect ( getObjectValue ( testObject , "user.metadata" , "default" ) ) . toBe ( "default" ) ;
162+ expect ( getObjectValue ( testObject , "user.metadata.something" , "fallback" ) ) . toBe ( "fallback" ) ;
163+ } ) ;
164+
165+ it ( "handles edge cases with dot notation" , ( ) => {
166+ const edgeObject = {
167+ "" : "empty key" ,
168+ "key.with.dots" : "literal dots" ,
169+ normal : {
170+ "" : "nested empty key" ,
171+ "key.with.dots" : "nested literal dots" ,
172+ } ,
173+ } ;
174+
175+ // Empty string key
176+ expect ( getObjectValue ( edgeObject , "" ) ) . toBe ( "empty key" ) ;
177+ expect ( getObjectValue ( edgeObject , "normal." ) ) . toBe ( "nested empty key" ) ;
178+
179+ // Keys that contain literal dots (these won't work with dot notation)
180+ expect ( getObjectValue ( edgeObject , "key.with.dots" ) ) . toBeUndefined ( ) ;
181+ expect ( getObjectValue ( edgeObject , "normal.key.with.dots" ) ) . toBeUndefined ( ) ;
182+ } ) ;
183+
184+ it ( "works with arrays using numeric indices" , ( ) => {
185+ const arrayObject = {
186+ items : [ { name : "first" , value : 1 } , { name : "second" , nested : { deep : "value" } , value : 2 } , "string item" ] ,
187+ matrix : [
188+ [ 1 , 2 , 3 ] ,
189+ [ 4 , 5 , 6 ] ,
190+ ] ,
191+ } ;
192+
193+ expect ( getObjectValue ( arrayObject , "items.0.name" ) ) . toBe ( "first" ) ;
194+ expect ( getObjectValue ( arrayObject , "items.1.value" ) ) . toBe ( 2 ) ;
195+ expect ( getObjectValue ( arrayObject , "items.1.nested.deep" ) ) . toBe ( "value" ) ;
196+ expect ( getObjectValue ( arrayObject , "items.2" ) ) . toBe ( "string item" ) ;
197+ expect ( getObjectValue ( arrayObject , "matrix.0.1" ) ) . toBe ( 2 ) ;
198+ expect ( getObjectValue ( arrayObject , "matrix.1.2" ) ) . toBe ( 6 ) ;
199+
200+ // Non-existent array indices
201+ expect ( getObjectValue ( arrayObject , "items.5" , "default" ) ) . toBe ( "default" ) ;
202+ expect ( getObjectValue ( arrayObject , "matrix.0.5" , "missing" ) ) . toBe ( "missing" ) ;
203+ } ) ;
204+ } ) ;
56205} ) ;
0 commit comments