@@ -268,6 +268,156 @@ def test_population_limit_enforcement(self):
268268 # Restore original limit
269269 self .db .config .population_size = original_limit
270270
271+ def test_calculate_complexity_bin_adaptive (self ):
272+ """Test adaptive complexity binning with multiple programs"""
273+ # Add programs with different complexities
274+ programs = [
275+ Program (id = "short" , code = "x=1" , metrics = {"score" : 0.5 }),
276+ Program (id = "medium" , code = "def func():\n return x*2\n pass" , metrics = {"score" : 0.5 }),
277+ Program (id = "long" , code = "def complex_function():\n result = []\n for i in range(100):\n result.append(i*2)\n return result" , metrics = {"score" : 0.5 }),
278+ ]
279+
280+ for program in programs :
281+ self .db .add (program )
282+
283+ # Test binning for different complexity values
284+ short_bin = self .db ._calculate_complexity_bin (len ("x=1" ))
285+ medium_bin = self .db ._calculate_complexity_bin (len ("def func():\n return x*2\n pass" ))
286+ long_bin = self .db ._calculate_complexity_bin (len ("def complex_function():\n result = []\n for i in range(100):\n result.append(i*2)\n return result" ))
287+
288+ # Bins should be different and within valid range
289+ self .assertNotEqual (short_bin , long_bin )
290+ self .assertGreaterEqual (short_bin , 0 )
291+ self .assertLess (short_bin , self .db .feature_bins )
292+ self .assertGreaterEqual (long_bin , 0 )
293+ self .assertLess (long_bin , self .db .feature_bins )
294+
295+ def test_calculate_complexity_bin_cold_start (self ):
296+ """Test complexity binning during cold start (< 2 programs)"""
297+ # Empty database - should use fixed range
298+ bin_idx = self .db ._calculate_complexity_bin (500 )
299+
300+ self .assertGreaterEqual (bin_idx , 0 )
301+ self .assertLess (bin_idx , self .db .feature_bins )
302+
303+ # Add one program - still cold start
304+ program = Program (id = "single" , code = "x=1" , metrics = {"score" : 0.5 })
305+ self .db .add (program )
306+
307+ bin_idx = self .db ._calculate_complexity_bin (500 )
308+ self .assertGreaterEqual (bin_idx , 0 )
309+ self .assertLess (bin_idx , self .db .feature_bins )
310+
311+ def test_calculate_diversity_bin_adaptive (self ):
312+ """Test adaptive diversity binning with multiple programs"""
313+ # Add programs with different code structures for diversity testing
314+ programs = [
315+ Program (id = "simple" , code = "x = 1" , metrics = {"score" : 0.5 }),
316+ Program (id = "function" , code = "def add(a, b):\n return a + b" , metrics = {"score" : 0.5 }),
317+ Program (id = "loop" , code = "for i in range(10):\n print(i)\n x += i" , metrics = {"score" : 0.5 }),
318+ Program (id = "complex" , code = "class MyClass:\n def __init__(self):\n self.data = []\n def process(self, items):\n return [x*2 for x in items]" , metrics = {"score" : 0.5 }),
319+ ]
320+
321+ for program in programs :
322+ self .db .add (program )
323+
324+ # Test binning for different diversity values
325+ # Use fast diversity to calculate test values
326+ simple_prog = programs [0 ]
327+ complex_prog = programs [3 ]
328+
329+ # Calculate diversity for simple vs complex programs
330+ simple_diversity = self .db ._fast_code_diversity (simple_prog .code , complex_prog .code )
331+
332+ # Test the binning
333+ bin_idx = self .db ._calculate_diversity_bin (simple_diversity )
334+
335+ # Should be within valid range
336+ self .assertGreaterEqual (bin_idx , 0 )
337+ self .assertLess (bin_idx , self .db .feature_bins )
338+
339+ def test_calculate_diversity_bin_cold_start (self ):
340+ """Test diversity binning during cold start (< 2 programs)"""
341+ # Empty database - should use fixed range
342+ bin_idx = self .db ._calculate_diversity_bin (500.0 )
343+
344+ self .assertGreaterEqual (bin_idx , 0 )
345+ self .assertLess (bin_idx , self .db .feature_bins )
346+
347+ # Add one program - still cold start
348+ program = Program (id = "single" , code = "x=1" , metrics = {"score" : 0.5 })
349+ self .db .add (program )
350+
351+ bin_idx = self .db ._calculate_diversity_bin (500.0 )
352+ self .assertGreaterEqual (bin_idx , 0 )
353+ self .assertLess (bin_idx , self .db .feature_bins )
354+
355+ def test_calculate_diversity_bin_identical_programs (self ):
356+ """Test diversity binning when all programs have identical diversity"""
357+ # Add multiple identical programs
358+ for i in range (3 ):
359+ program = Program (
360+ id = f"identical_{ i } " ,
361+ code = "x = 1" , # Same code
362+ metrics = {"score" : 0.5 }
363+ )
364+ self .db .add (program )
365+
366+ # Test binning - should handle zero range gracefully
367+ bin_idx = self .db ._calculate_diversity_bin (0.0 )
368+
369+ self .assertGreaterEqual (bin_idx , 0 )
370+ self .assertLess (bin_idx , self .db .feature_bins )
371+
372+ def test_fast_code_diversity_function (self ):
373+ """Test the _fast_code_diversity function"""
374+ # Test identical code
375+ code1 = "def test(): pass"
376+ code2 = "def test(): pass"
377+ diversity = self .db ._fast_code_diversity (code1 , code2 )
378+ self .assertEqual (diversity , 0.0 )
379+
380+ # Test different code
381+ code1 = "x = 1"
382+ code2 = "def complex_function():\n return [i*2 for i in range(100)]"
383+ diversity = self .db ._fast_code_diversity (code1 , code2 )
384+ self .assertGreater (diversity , 0.0 )
385+
386+ # Test length difference
387+ short_code = "x = 1"
388+ long_code = "x = 1" + "a" * 100
389+ diversity = self .db ._fast_code_diversity (short_code , long_code )
390+ self .assertGreater (diversity , 0.0 )
391+
392+ def test_diversity_feature_integration (self ):
393+ """Test diversity feature calculation in feature coordinates"""
394+ # Add programs with different structures
395+ programs = [
396+ Program (id = "prog1" , code = "x = 1" , metrics = {"score" : 0.5 }),
397+ Program (id = "prog2" , code = "def func():\n return 2" , metrics = {"score" : 0.5 }),
398+ Program (id = "prog3" , code = "for i in range(5):\n print(i)" , metrics = {"score" : 0.5 }),
399+ ]
400+
401+ for program in programs :
402+ self .db .add (program )
403+
404+ # Create a test program with diversity feature enabled
405+ test_config = self .db .config
406+ test_config .feature_dimensions = ["score" , "complexity" , "diversity" ]
407+
408+ test_program = Program (id = "test" , code = "def test(): return 42" , metrics = {"score" : 0.7 })
409+
410+ # Calculate feature coordinates - should include diversity dimension
411+ coords = self .db ._calculate_feature_coords (test_program )
412+
413+ # Should have 3 coordinates for score, complexity, and diversity
414+ self .assertEqual (len (coords ), 3 )
415+
416+ # All coordinates should be within valid range
417+ for coord in coords :
418+ self .assertGreaterEqual (coord , 0 )
419+ self .assertLess (coord , self .db .feature_bins )
420+
271421
272422if __name__ == "__main__" :
273423 unittest .main ()
0 commit comments