import unittest, results, strutils import ../src/bloom from random import rand, randomize suite "bloom filter": setup: let nElementsToTest = 10000 let bfResult = initializeBloomFilter(capacity = nElementsToTest, errorRate = 0.001) check bfResult.isOk var bf = bfResult.get randomize(2882) # Seed the RNG var sampleChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" testElements = newSeq[string](nElementsToTest) for i in 0.. 12 let errorCase = getMOverNBitsForK(k = 13, targetError = 0.01) check errorCase.isErr check errorCase.error == "K must be <= 12 if forceNBitsPerElem is not also specified." # Test error case for unachievable error rate let errorCase2 = getMOverNBitsForK(k = 2, targetError = 0.00001) check errorCase2.isErr check errorCase2.error == "Specified value of k and error rate not achievable using less than 4 bytes / element." # Test success cases let case1 = getMOverNBitsForK(k = 2, targetError = 0.1) check case1.isOk check case1.value == 6 let case2 = getMOverNBitsForK(k = 7, targetError = 0.01) check case2.isOk check case2.value == 10 let case3 = getMOverNBitsForK(k = 7, targetError = 0.001) check case3.isOk check case3.value == 16 let bf2Result = initializeBloomFilter(10000, 0.001, k = 4, forceNBitsPerElem = 20) check bf2Result.isOk let bf2 = bf2Result.get check bf2.kHashes == 4 check bf2.mBits == 200000 test "string representation": let bf3Result = initializeBloomFilter(1000, 0.01, k = 4) check bf3Result.isOk let bf3 = bf3Result.get let str = $bf3 check str.contains("1000") # Capacity check str.contains("4 hash") # Hash functions check str.contains("1.0e-02") # Error rate in scientific notation suite "bloom filter special cases": test "different patterns of strings": const testSize = 10_000 let patterns = @[ "shortstr", repeat("a", 1000), # Very long string "special@#$%^&*()", # Special characters "unicode→★∑≈", # Unicode characters repeat("pattern", 10) # Repeating pattern ] let bfResult = initializeBloomFilter(testSize, 0.01) check bfResult.isOk var bf = bfResult.get var inserted = newSeq[string](testSize) # Test pattern handling for pattern in patterns: bf.insert(pattern) assert bf.lookup(pattern), "failed lookup pattern: " & pattern # Test general insertion and lookup for i in 0..