1+ // File: pkg/config/config_test.go
2+
13package config
24
35import (
46 "os"
7+ "reflect"
58 "testing"
69)
710
@@ -36,6 +39,29 @@ func TestLoadUnreadableFile(t *testing.T) {
3639 }
3740}
3841
42+ /*
43+ TestLoadInvalidJSONFormat ensures Load correctly returns an error for malformed JSON.
44+ */
45+ func TestLoadInvalidJSONFormat (t * testing.T ) {
46+ tmpFile , err := os .CreateTemp ("" , "invalid_json_*.json" )
47+ if err != nil {
48+ t .Fatalf ("Failed to create temp file: %v" , err )
49+ }
50+ defer os .Remove (tmpFile .Name ())
51+
52+ // Invalid JSON (missing closing brace)
53+ invalidJSON := `{"url": {"base": "http://example.org"`
54+ if _ , err := tmpFile .Write ([]byte (invalidJSON )); err != nil {
55+ t .Fatalf ("Failed to write to temp file: %v" , err )
56+ }
57+ tmpFile .Close ()
58+
59+ _ , err = Load (tmpFile .Name ())
60+ if err == nil {
61+ t .Fatalf ("Expected error for malformed JSON, got nil" )
62+ }
63+ }
64+
3965/*
4066TestLoadVerboseMode ensures that verbose mode triggers PrintNonEmptyFields.
4167*/
@@ -65,6 +91,87 @@ func TestLoadVerboseMode(t *testing.T) {
6591 }
6692}
6793
94+ /*
95+ TestOverrideWithInvalidField ensures that OverrideWithCLI skips invalid fields safely.
96+ */
97+ func TestOverrideWithInvalidField (t * testing.T ) {
98+ cfg := & Config {}
99+ cfg .ApplyDefaults ()
100+
101+ overrides := Config {}
102+ field := reflect .ValueOf (& overrides ).Elem ().FieldByName ("InvalidField" )
103+
104+ // Ensure the field exists and can be modified
105+ if field .IsValid () && field .CanSet () {
106+ field .Set (reflect .ValueOf (42 )) // Invalid field
107+ }
108+
109+ defer func () {
110+ if r := recover (); r != nil {
111+ t .Fatalf ("Expected safe handling of invalid fields, but got panic: %v" , r )
112+ }
113+ }()
114+
115+ cfg .OverrideWithCLI (overrides )
116+ }
117+
118+ /*
119+ TestOverrideWithInvalidNestedField ensures that OverrideWithCLI skips invalid nested fields safely.
120+ */
121+ func TestOverrideWithInvalidNestedField (t * testing.T ) {
122+ cfg := & Config {}
123+ cfg .ApplyDefaults ()
124+
125+ overrides := Config {}
126+
127+ // Get the field reference
128+ field := reflect .ValueOf (& overrides ).Elem ().FieldByName ("URL" )
129+
130+ // Ensure the field exists and is of type struct before attempting an invalid override
131+ if field .IsValid () && field .Kind () == reflect .Struct {
132+ defer func () {
133+ if r := recover (); r != nil {
134+ t .Fatalf ("Expected safe handling of invalid nested fields, but got panic: %v" , r )
135+ }
136+ }()
137+
138+ // Try setting an invalid value (int) but ensure it's prevented before setting
139+ invalidValue := reflect .ValueOf (42 )
140+ if field .CanSet () && field .Kind () == invalidValue .Kind () { // Ensure types match
141+ field .Set (invalidValue ) // This should NOT execute due to validation.
142+ }
143+ }
144+
145+ // Ensure the override function does not crash on incorrect input
146+ cfg .OverrideWithCLI (overrides )
147+ }
148+
149+ /*
150+ TestOverrideWithValidSubField ensures that OverrideWithCLI correctly overrides valid subfields.
151+ */
152+ func TestOverrideWithValidSubField (t * testing.T ) {
153+ cfg := & Config {}
154+ cfg .ApplyDefaults ()
155+
156+ overrides := Config {
157+ ParseRules : struct {
158+ Title string `json:"title,omitempty"`
159+ MetaDescription string `json:"metaDescription,omitempty"`
160+ ArticleContent string `json:"articleContent,omitempty"`
161+ Author string `json:"author,omitempty"`
162+ DatePublished string `json:"datePublished,omitempty"`
163+ }{
164+ Title : "New Title" ,
165+ },
166+ }
167+
168+ cfg .OverrideWithCLI (overrides )
169+
170+ if cfg .ParseRules .Title != "New Title" {
171+ t .Errorf ("Expected Title to be 'New Title', got '%s'" , cfg .ParseRules .Title )
172+ }
173+ }
174+
68175/*
69176TestOverrideWithEmptySlices ensures that OverrideWithCLI skips empty slice values.
70177*/
@@ -88,3 +195,33 @@ func TestOverrideWithEmptySlices(t *testing.T) {
88195 t .Errorf ("Expected Routes to remain unchanged, but they were overridden with an empty slice." )
89196 }
90197}
198+
199+ /*
200+ TestOverrideWithValidFields ensures that OverrideWithCLI correctly applies non-zero overrides.
201+ */
202+ func TestOverrideWithValidFields (t * testing.T ) {
203+ cfg := & Config {}
204+ cfg .ApplyDefaults ()
205+
206+ overrides := Config {
207+ ScrapingOptions : struct {
208+ MaxDepth int `json:"maxDepth"`
209+ RateLimit float64 `json:"rateLimit"`
210+ RetryAttempts int `json:"retryAttempts"`
211+ UserAgent string `json:"userAgent"`
212+ }{
213+ MaxDepth : 5 ,
214+ RateLimit : 2.5 ,
215+ },
216+ }
217+
218+ cfg .OverrideWithCLI (overrides )
219+
220+ if cfg .ScrapingOptions .MaxDepth != 5 {
221+ t .Errorf ("Expected MaxDepth to be overridden to 5, got '%d'" , cfg .ScrapingOptions .MaxDepth )
222+ }
223+
224+ if cfg .ScrapingOptions .RateLimit != 2.5 {
225+ t .Errorf ("Expected RateLimit to be overridden to 2.5, got '%f'" , cfg .ScrapingOptions .RateLimit )
226+ }
227+ }
0 commit comments