@@ -89,129 +89,86 @@ describe("json", function () {
8989 expect ( settings . get ( "json.settings.illegalString" ) ) . eq ( "[unclosed" , "is illegal string" ) ;
9090 } ) ;
9191
92- it ( "should parse json with single-line comments" , async ( ) => {
93- const jsoncValue = `{
94- // This is a single-line comment
95- "database": {
96- "host": "localhost", // Another comment
97- "port": 5432
92+ it ( "should load json values with comments" , async ( ) => {
93+ // Test various comment styles and positions
94+ const mixedCommentStylesValue = `{
95+ // Single line comment at start
96+ "ApiSettings": {
97+ "BaseUrl": "https://api.example.com", // Inline single line
98+ /* Multi-line comment
99+ spanning multiple lines */
100+ "ApiKey": "secret-key",
101+ "Endpoints": [
102+ // Comment before array element
103+ "/users",
104+ /* Comment between elements */
105+ "/orders",
106+ "/products" // Comment after element
107+ ]
98108 },
99- "debug": true
109+ // Test edge cases
110+ "StringWithSlashes": "This is not a // comment",
111+ "StringWithStars": "This is not a /* comment */",
112+ "UrlValue": "https://example.com/path", // This is a real comment
113+ "EmptyComment": "value", //
114+ /**/
115+ "AfterEmptyComment": "value2"
116+ /* Final multi-line comment */
100117 }` ;
101- const jsoncKeyValue = createMockedJsonKeyValue ( "jsonc.settings.withComments" , jsoncValue ) ;
102- mockAppConfigurationClientListConfigurationSettings ( [ [ jsoncKeyValue ] ] ) ;
103118
104- const connectionString = createMockedConnectionString ( ) ;
105- const settings = await load ( connectionString ) ;
106- expect ( settings ) . not . undefined ;
107- const config = settings . get < any > ( "jsonc.settings.withComments" ) ;
108- expect ( config ) . not . undefined ;
109- expect ( config . database ) . not . undefined ;
110- expect ( config . database . host ) . eq ( "localhost" ) ;
111- expect ( config . database . port ) . eq ( 5432 ) ;
112- expect ( config . debug ) . eq ( true ) ;
113- } ) ;
119+ // Test invalid JSON with comments
120+ const invalidJsonWithCommentsValue = `// This is a comment
121+ { invalid json structure
122+ // Another comment
123+ missing quotes and braces` ;
114124
115- it ( "should parse json with multi-line comments" , async ( ) => {
116- const jsoncValue = `{
117- /*
118- * This is a multi-line comment
119- * describing the configuration
120- */
121- "app": {
122- "name": "TestApp",
123- /* inline multi-line comment */ "version": "1.0.0"
124- },
125- /*
126- "disabled": "this entire section is commented out"
127- */
128- "enabled": true
129- }` ;
130- const jsoncKeyValue = createMockedJsonKeyValue ( "jsonc.settings.multilineComments" , jsoncValue ) ;
131- mockAppConfigurationClientListConfigurationSettings ( [ [ jsoncKeyValue ] ] ) ;
125+ // Test only comments (should be invalid JSON)
126+ const onlyCommentsValue = `
127+ // Just comments
128+ /* No actual content */
129+ ` ;
132130
133- const connectionString = createMockedConnectionString ( ) ;
134- const settings = await load ( connectionString ) ;
135- expect ( settings ) . not . undefined ;
136- const config = settings . get < any > ( "jsonc.settings.multilineComments" ) ;
137- expect ( config ) . not . undefined ;
138- expect ( config . app ) . not . undefined ;
139- expect ( config . app . name ) . eq ( "TestApp" ) ;
140- expect ( config . app . version ) . eq ( "1.0.0" ) ;
141- expect ( config . enabled ) . eq ( true ) ;
142- expect ( config . disabled ) . undefined ; // Should be undefined as it's commented out
143- } ) ;
131+ const keyValues = [
132+ createMockedJsonKeyValue ( "MixedCommentStyles" , mixedCommentStylesValue ) ,
133+ createMockedJsonKeyValue ( "InvalidJsonWithComments" , invalidJsonWithCommentsValue ) ,
134+ createMockedJsonKeyValue ( "OnlyComments" , onlyCommentsValue )
135+ ] ;
144136
145- it ( "should parse json with mixed comment types" , async ( ) => {
146- const jsoncValue = `{
147- // Configuration for the application
148- "application": {
149- "name": "Azure App Config Test", // Application name
150- "version": "2.0.0",
151- /*
152- * Environment settings
153- * These can be overridden per environment
154- */
155- "environment": {
156- "development": {
157- "debug": true,
158- "logLevel": "debug"
159- },
160- "production": {
161- "debug": false,
162- "logLevel": "error"
163- }
164- }
165- },
166- // Features configuration
167- "features": [
168- "authentication",
169- "logging",
170- /* "experimental-feature", */ // Commented out feature
171- "monitoring"
172- ]
173- }` ;
174- const jsoncKeyValue = createMockedJsonKeyValue ( "jsonc.settings.complex" , jsoncValue ) ;
175- mockAppConfigurationClientListConfigurationSettings ( [ [ jsoncKeyValue ] ] ) ;
137+ mockAppConfigurationClientListConfigurationSettings ( [ keyValues ] ) ;
176138
177139 const connectionString = createMockedConnectionString ( ) ;
178140 const settings = await load ( connectionString ) ;
179141 expect ( settings ) . not . undefined ;
180- const config = settings . get < any > ( "jsonc.settings.complex" ) ;
181- expect ( config ) . not . undefined ;
182- expect ( config . application ) . not . undefined ;
183- expect ( config . application . name ) . eq ( "Azure App Config Test" ) ;
184- expect ( config . application . version ) . eq ( "2.0.0" ) ;
185- expect ( config . application . environment ) . not . undefined ;
186- expect ( config . application . environment . development ) . not . undefined ;
187- expect ( config . application . environment . development . debug ) . eq ( true ) ;
188- expect ( config . application . environment . development . logLevel ) . eq ( "debug" ) ;
189- expect ( config . application . environment . production ) . not . undefined ;
190- expect ( config . application . environment . production . debug ) . eq ( false ) ;
191- expect ( config . application . environment . production . logLevel ) . eq ( "error" ) ;
192- expect ( config . features ) . not . undefined ;
193- expect ( Array . isArray ( config . features ) ) . eq ( true ) ;
194- expect ( config . features . length ) . eq ( 3 ) ;
195- expect ( config . features [ 0 ] ) . eq ( "authentication" ) ;
196- expect ( config . features [ 1 ] ) . eq ( "logging" ) ;
197- expect ( config . features [ 2 ] ) . eq ( "monitoring" ) ;
198- // Should not contain the commented out "experimental-feature"
199- expect ( config . features . includes ( "experimental-feature" ) ) . eq ( false ) ;
200- } ) ;
201142
202- it ( "should fallback to string value if json with comments parsing fails" , async ( ) => {
203- const invalidJsoncValue = `{
204- // This is invalid JSON with unclosed bracket
205- "test": "value"` ;
206- const jsoncKeyValue = createMockedJsonKeyValue ( "jsonc.settings.invalid" , invalidJsoncValue ) ;
207- mockAppConfigurationClientListConfigurationSettings ( [ [ jsoncKeyValue ] ] ) ;
208-
209- const connectionString = createMockedConnectionString ( ) ;
210- const settings = await load ( connectionString ) ;
211- expect ( settings ) . not . undefined ;
212- const config = settings . get ( "jsonc.settings.invalid" ) ;
213- expect ( config ) . not . undefined ;
214- expect ( typeof config ) . eq ( "string" , "should fallback to string value" ) ;
215- expect ( config ) . eq ( invalidJsoncValue ) ;
143+ // Verify mixed comment styles are properly parsed
144+ const mixedConfig = settings . get < any > ( "MixedCommentStyles" ) ;
145+ expect ( mixedConfig ) . not . undefined ;
146+ expect ( mixedConfig . ApiSettings ) . not . undefined ;
147+ expect ( mixedConfig . ApiSettings . BaseUrl ) . eq ( "https://api.example.com" ) ;
148+ expect ( mixedConfig . ApiSettings . ApiKey ) . eq ( "secret-key" ) ;
149+ expect ( mixedConfig . ApiSettings . Endpoints ) . not . undefined ;
150+ expect ( Array . isArray ( mixedConfig . ApiSettings . Endpoints ) ) . eq ( true ) ;
151+ expect ( mixedConfig . ApiSettings . Endpoints [ 0 ] ) . eq ( "/users" ) ;
152+ expect ( mixedConfig . ApiSettings . Endpoints [ 1 ] ) . eq ( "/orders" ) ;
153+ expect ( mixedConfig . ApiSettings . Endpoints [ 2 ] ) . eq ( "/products" ) ;
154+
155+ // Verify edge cases where comment-like text appears in strings
156+ expect ( mixedConfig . StringWithSlashes ) . eq ( "This is not a // comment" ) ;
157+ expect ( mixedConfig . StringWithStars ) . eq ( "This is not a /* comment */" ) ;
158+ expect ( mixedConfig . UrlValue ) . eq ( "https://example.com/path" ) ;
159+ expect ( mixedConfig . EmptyComment ) . eq ( "value" ) ;
160+ expect ( mixedConfig . AfterEmptyComment ) . eq ( "value2" ) ;
161+
162+ // Invalid JSON should fall back to string value
163+ const invalidConfig = settings . get ( "InvalidJsonWithComments" ) ;
164+ expect ( invalidConfig ) . not . undefined ;
165+ expect ( typeof invalidConfig ) . eq ( "string" ) ;
166+ expect ( invalidConfig ) . eq ( invalidJsonWithCommentsValue ) ;
167+
168+ // Only comments should be treated as string value (invalid JSON)
169+ const onlyCommentsConfig = settings . get ( "OnlyComments" ) ;
170+ expect ( onlyCommentsConfig ) . not . undefined ;
171+ expect ( typeof onlyCommentsConfig ) . eq ( "string" ) ;
172+ expect ( onlyCommentsConfig ) . eq ( onlyCommentsValue ) ;
216173 } ) ;
217174} ) ;
0 commit comments