src/test-similarity-calculator.lua
1#!/usr/bin/env lua
2
3-- Test script for modular similarity calculator
4-- Validates mathematical correctness and algorithm functionality
5
6local DIR = "/mnt/mtwo/programming/ai-stuff/neocities-modernization"
7
8package.path = package.path .. ';' .. DIR .. '/?.lua;' .. DIR .. '/libs/?.lua'
9
10local similarity_module = require("src.similarity-calculator")
11local SimilarityCalculator = similarity_module.SimilarityCalculator
12local utils = require("libs.utils")
13
14-- {{{ function test_all_algorithms
15function test_all_algorithms()
16 print("๐งช Testing Modular Similarity Calculator")
17 print("========================================")
18
19 local calculator = SimilarityCalculator:new("cosine")
20 local algorithms = calculator.supported_algorithms
21
22 local overall_results = {
23 total_algorithms = #algorithms,
24 passed_algorithms = 0,
25 failed_algorithms = 0,
26 algorithm_results = {}
27 }
28
29 for _, algorithm in ipairs(algorithms) do
30 print(string.format("\n๐ Testing Algorithm: %s", algorithm))
31 print(string.format("Description: %s", ""))
32
33 local calc = SimilarityCalculator:new(algorithm)
34 print(string.format("Description: %s", calc:get_algorithm_description()))
35
36 local validation_result = calc:validate_implementation()
37 overall_results.algorithm_results[algorithm] = validation_result
38
39 if validation_result.all_tests_passed then
40 overall_results.passed_algorithms = overall_results.passed_algorithms + 1
41 print("โ
All validation tests PASSED")
42 else
43 overall_results.failed_algorithms = overall_results.failed_algorithms + 1
44 print("โ Some validation tests FAILED")
45 end
46
47 -- Show detailed test results
48 for _, test_result in ipairs(validation_result.validation_results) do
49 local status = test_result.passed and "โ
" or "โ"
50 print(string.format(" %s %s: expected %.4f, got %.4f (diff: %.4f)",
51 status, test_result.test_name,
52 test_result.expected, test_result.calculated,
53 test_result.difference))
54 end
55 end
56
57 return overall_results
58end
59-- }}}
60
61-- {{{ function test_realistic_embeddings
62function test_realistic_embeddings()
63 print("\n\n๐ฌ Testing with Realistic Embedding Vectors")
64 print("==========================================")
65
66 -- Create some realistic-looking embedding vectors
67 local poem_about_love = {0.8, 0.1, 0.6, -0.2, 0.4, 0.9, -0.1, 0.3}
68 local poem_about_nature = {0.2, 0.7, -0.3, 0.8, 0.1, 0.4, 0.6, -0.2}
69 local similar_love_poem = {0.7, 0.2, 0.5, -0.1, 0.3, 0.8, 0.0, 0.4}
70
71 local test_algorithms = {"cosine", "euclidean", "angular", "pearson_correlation"}
72
73 print("Test vectors:")
74 print(string.format("Love poem 1: %s", table.concat(poem_about_love, ", ")))
75 print(string.format("Nature poem: %s", table.concat(poem_about_nature, ", ")))
76 print(string.format("Love poem 2: %s", table.concat(similar_love_poem, ", ")))
77
78 for _, algorithm in ipairs(test_algorithms) do
79 local calc = SimilarityCalculator:new(algorithm)
80
81 local love1_nature = calc:calculate(poem_about_love, poem_about_nature)
82 local love1_love2 = calc:calculate(poem_about_love, similar_love_poem)
83
84 print(string.format("\n%s Algorithm:", algorithm))
85 print(string.format(" Love1 <-> Nature: %.4f", love1_nature))
86 print(string.format(" Love1 <-> Love2: %.4f", love1_love2))
87
88 if love1_love2 > love1_nature then
89 print(" โ
Similar poems have higher similarity (expected)")
90 else
91 print(" โ ๏ธ Similar poems have lower similarity (unexpected)")
92 end
93 end
94end
95-- }}}
96
97-- {{{ function test_error_handling
98function test_error_handling()
99 print("\n\n๐จ Testing Error Handling")
100 print("========================")
101
102 local tests = {
103 {
104 name = "Unsupported algorithm",
105 test_func = function()
106 SimilarityCalculator:new("nonexistent_algorithm")
107 end
108 },
109 {
110 name = "Mismatched vector dimensions",
111 test_func = function()
112 local calc = SimilarityCalculator:new("cosine")
113 calc:calculate({1, 2, 3}, {1, 2}) -- Different lengths
114 end
115 },
116 {
117 name = "Nil embedding",
118 test_func = function()
119 local calc = SimilarityCalculator:new("cosine")
120 calc:calculate(nil, {1, 2, 3})
121 end
122 }
123 }
124
125 for _, test in ipairs(tests) do
126 local success, error_message = pcall(test.test_func)
127 if success then
128 print(string.format("โ %s: Expected error but got success", test.name))
129 else
130 print(string.format("โ
%s: Correctly caught error - %s", test.name, error_message))
131 end
132 end
133end
134-- }}}
135
136-- {{{ function main
137function main()
138 local overall_results = test_all_algorithms()
139 test_realistic_embeddings()
140 test_error_handling()
141
142 print("\n\n๐ Overall Results Summary")
143 print("=========================")
144 print(string.format("Total algorithms tested: %d", overall_results.total_algorithms))
145 print(string.format("Algorithms passed: %d", overall_results.passed_algorithms))
146 print(string.format("Algorithms failed: %d", overall_results.failed_algorithms))
147
148 if overall_results.failed_algorithms == 0 then
149 print("\n๐ All similarity algorithms working correctly!")
150 return 0
151 else
152 print("\nโ ๏ธ Some algorithms need attention")
153 return 1
154 end
155end
156-- }}}
157
158-- Run tests if executed directly
159if arg and arg[0] and arg[0]:match("test%-similarity%-calculator%.lua$") then
160 os.exit(main())
161end
162
163return {
164 test_all_algorithms = test_all_algorithms,
165 test_realistic_embeddings = test_realistic_embeddings,
166 test_error_handling = test_error_handling,
167 main = main
168}