@@ -39,14 +39,55 @@ public void testCreateInstanceIsFunction() {
3939 assertNotNull (Featurevisor .class .getConstructors ());
4040 }
4141
42+ @ Test
43+ public void testCreateInstanceWithNoParameters () {
44+ // Test the simplest createInstance() method
45+ Featurevisor sdk = Featurevisor .createInstance ();
46+
47+ assertNotNull (sdk );
48+ // Should have default logger and empty datafile
49+ assertNotNull (sdk .getRevision ());
50+ assertNull (sdk .getVariation ("nonExistentFeature" ));
51+ }
52+
4253 @ Test
4354 public void testCreateInstanceWithDatafileContent () {
4455 // Create datafile content using JSON string for better readability
4556 String datafileJson = """
4657 {
4758 "schemaVersion": "2",
4859 "revision": "1.0",
49- "features": {},
60+ "features": {
61+ "test": {
62+ "key": "test",
63+ "bucketBy": "userId",
64+ "variations": [
65+ {
66+ "value": "control"
67+ },
68+ {
69+ "value": "treatment"
70+ }
71+ ],
72+ "traffic": [
73+ {
74+ "key": "1",
75+ "segments": "*",
76+ "percentage": 100000,
77+ "allocation": [
78+ {
79+ "variation": "control",
80+ "range": [0, 100000]
81+ },
82+ {
83+ "variation": "treatment",
84+ "range": [0, 0]
85+ }
86+ ]
87+ }
88+ ]
89+ }
90+ },
5091 "segments": {}
5192 }""" ;
5293
@@ -58,14 +99,231 @@ public void testCreateInstanceWithDatafileContent() {
5899 return ;
59100 }
60101
61- Featurevisor sdk = new Featurevisor (new Featurevisor .Options ().datafile (datafile ));
102+ // Test createInstance with DatafileContent
103+ Featurevisor sdk = Featurevisor .createInstance (datafile );
104+
105+ assertNotNull (sdk );
106+ assertEquals ("1.0" , sdk .getRevision ());
107+ assertEquals ("control" , sdk .getVariation ("test" , Map .of ("userId" , "123" )));
108+ }
109+
110+ @ Test
111+ public void testCreateInstanceWithDatafileString () {
112+ // Test createInstance with datafile string
113+ String datafileJson = """
114+ {
115+ "schemaVersion": "2",
116+ "revision": "2.0",
117+ "features": {
118+ "test": {
119+ "key": "test",
120+ "bucketBy": "userId",
121+ "variations": [
122+ {
123+ "value": "control"
124+ },
125+ {
126+ "value": "treatment"
127+ }
128+ ],
129+ "traffic": [
130+ {
131+ "key": "1",
132+ "segments": "*",
133+ "percentage": 100000,
134+ "allocation": [
135+ {
136+ "variation": "control",
137+ "range": [0, 0]
138+ },
139+ {
140+ "variation": "treatment",
141+ "range": [0, 100000]
142+ }
143+ ]
144+ }
145+ ]
146+ }
147+ },
148+ "segments": {}
149+ }""" ;
150+
151+ // Test createInstance with datafile string
152+ Featurevisor sdk = Featurevisor .createInstance (datafileJson );
153+
154+ assertNotNull (sdk );
155+ assertEquals ("2.0" , sdk .getRevision ());
156+ assertEquals ("treatment" , sdk .getVariation ("test" , Map .of ("userId" , "123" )));
157+ }
158+
159+ @ Test
160+ public void testCreateInstanceWithContext () {
161+ // Test createInstance with context
162+ Map <String , Object > context = Map .of (
163+ "userId" , "123" ,
164+ "country" , "us"
165+ );
166+
167+ Featurevisor sdk = Featurevisor .createInstance (context );
168+
169+ assertNotNull (sdk );
170+ // Context should be set
171+ Map <String , Object > retrievedContext = sdk .getContext ();
172+ assertEquals ("123" , retrievedContext .get ("userId" ));
173+ assertEquals ("us" , retrievedContext .get ("country" ));
174+ }
175+
176+ @ Test
177+ public void testCreateInstanceWithLogLevel () {
178+ // Test createInstance with log level
179+ Featurevisor sdk = Featurevisor .createInstance (Logger .LogLevel .DEBUG );
180+
181+ assertNotNull (sdk );
182+ // The logger should be set with DEBUG level
183+ // We can't directly access the logger level, but we can verify the instance was created
184+ assertNotNull (sdk .getRevision ());
185+ }
186+
187+ @ Test
188+ public void testCreateInstanceWithLogger () {
189+ // Test createInstance with custom logger
190+ Logger customLogger = Logger .createLogger (new Logger .CreateLoggerOptions ()
191+ .level (Logger .LogLevel .ERROR )
192+ .handler ((level , message , details ) -> {
193+ // Custom handler
194+ }));
195+
196+ Featurevisor sdk = Featurevisor .createInstance (customLogger );
197+
198+ assertNotNull (sdk );
199+ // The custom logger should be used
200+ assertNotNull (sdk .getRevision ());
201+ }
202+
203+ @ Test
204+ public void testCreateInstanceWithStickyFeatures () {
205+ // Test createInstance with sticky features (isSticky = true)
206+ Map <String , Object > sticky = new HashMap <>();
207+ Map <String , Object > testSticky = new HashMap <>();
208+ testSticky .put ("enabled" , true );
209+ testSticky .put ("variation" , "control" );
210+ sticky .put ("test" , testSticky );
211+
212+ Featurevisor sdk = Featurevisor .createInstance (sticky , true );
213+
214+ assertNotNull (sdk );
215+ // Sticky features should be set
216+ assertEquals ("control" , sdk .getVariation ("test" , Map .of ("userId" , "123" )));
217+ }
218+
219+ @ Test
220+ public void testCreateInstanceWithContextAsSticky () {
221+ // Test createInstance with context as sticky (isSticky = false)
222+ Map <String , Object > context = Map .of (
223+ "userId" , "123" ,
224+ "country" , "us"
225+ );
226+
227+ Featurevisor sdk = Featurevisor .createInstance (context , false );
228+
229+ assertNotNull (sdk );
230+ // Context should be set (not sticky)
231+ Map <String , Object > retrievedContext = sdk .getContext ();
232+ assertEquals ("123" , retrievedContext .get ("userId" ));
233+ assertEquals ("us" , retrievedContext .get ("country" ));
234+ }
235+
236+ @ Test
237+ public void testCreateInstanceWithNullOptions () {
238+ // Test createInstance with null options (should use defaults)
239+ Featurevisor sdk = Featurevisor .createInstance ((Featurevisor .Options ) null );
240+
241+ assertNotNull (sdk );
242+ assertNotNull (sdk .getRevision ());
243+ }
244+
245+ @ Test
246+ public void testCreateInstanceWithInvalidDatafileString () {
247+ // Test createInstance with invalid datafile string
248+ String invalidJson = "{ invalid json }" ;
249+
250+ // Should not throw exception, but should log error
251+ Featurevisor sdk = Featurevisor .createInstance (invalidJson );
62252
63- // Test that the SDK was created successfully
64253 assertNotNull (sdk );
65- // Test that getVariation returns null for non-existent feature (which is expected behavior)
254+ // Should have default empty datafile
66255 assertNull (sdk .getVariation ("test" ));
67256 }
68257
258+ @ Test
259+ public void testCreateInstanceWithOptionsBuilder () {
260+ // Test createInstance with Options builder pattern
261+ String datafileJson = """
262+ {
263+ "schemaVersion": "2",
264+ "revision": "3.0",
265+ "features": {
266+ "test": {
267+ "key": "test",
268+ "bucketBy": "userId",
269+ "variations": [
270+ {
271+ "value": "control"
272+ },
273+ {
274+ "value": "treatment"
275+ }
276+ ],
277+ "traffic": [
278+ {
279+ "key": "1",
280+ "segments": "*",
281+ "percentage": 100000,
282+ "allocation": [
283+ {
284+ "variation": "control",
285+ "range": [0, 100000]
286+ },
287+ {
288+ "variation": "treatment",
289+ "range": [0, 0]
290+ }
291+ ]
292+ }
293+ ]
294+ }
295+ },
296+ "segments": {}
297+ }""" ;
298+
299+ DatafileContent datafile ;
300+ try {
301+ datafile = DatafileContent .fromJson (datafileJson );
302+ } catch (Exception e ) {
303+ fail ("Failed to parse datafile JSON: " + e .getMessage ());
304+ return ;
305+ }
306+
307+ Map <String , Object > context = Map .of ("userId" , "123" );
308+ Logger customLogger = Logger .createLogger (new Logger .CreateLoggerOptions ().level (Logger .LogLevel .INFO ));
309+
310+ // Test with Options builder
311+ Featurevisor .Options options = new Featurevisor .Options ()
312+ .datafile (datafile )
313+ .context (context )
314+ .logger (customLogger );
315+
316+ Featurevisor sdk = Featurevisor .createInstance (options );
317+
318+ assertNotNull (sdk );
319+ assertEquals ("3.0" , sdk .getRevision ());
320+ assertEquals ("control" , sdk .getVariation ("test" , context ));
321+
322+ // Context should be set
323+ Map <String , Object > retrievedContext = sdk .getContext ();
324+ assertEquals ("123" , retrievedContext .get ("userId" ));
325+ }
326+
69327 @ Test
70328 public void testConfigurePlainBucketBy () {
71329 final String [] capturedBucketKey = {"" };
0 commit comments