mirror of
https://github.com/metabolist/metatext.git
synced 2024-05-19 00:38:08 +00:00
133 lines
4.2 KiB
Swift
133 lines
4.2 KiB
Swift
// Copyright © 2020 Metabolist. All rights reserved.
|
|
|
|
@testable import CodableBloomFilter
|
|
import XCTest
|
|
|
|
final class CodableBloomFilterTests: XCTestCase {
|
|
func testHashes() {
|
|
XCTAssertEqual(Hash.djb232.apply("hash"), 2090320585)
|
|
XCTAssertEqual(Hash.djb2a32.apply("hash"), 2087809207)
|
|
XCTAssertEqual(Hash.sdbm32.apply("hash"), 385600046)
|
|
XCTAssertEqual(Hash.fnv132.apply("hash"), 3616638997)
|
|
XCTAssertEqual(Hash.fnv1a32.apply("hash"), 3469047761)
|
|
}
|
|
|
|
func testContains() throws {
|
|
var sut = BloomFilter<String>(hashes: [.sdbm32, .djb232], byteCount: 8)
|
|
|
|
sut.insert("lol")
|
|
sut.insert("ok")
|
|
|
|
XCTAssert(sut.contains("lol"))
|
|
XCTAssert(sut.contains("ok"))
|
|
XCTAssertFalse(sut.contains("wtf"))
|
|
XCTAssertFalse(sut.contains("no"))
|
|
}
|
|
|
|
func testData() throws {
|
|
var sut = BloomFilter<String>(hashes: [.sdbm32, .djb232], byteCount: 8)
|
|
|
|
sut.insert("lol")
|
|
sut.insert("ok")
|
|
|
|
XCTAssertEqual(sut.data, Data([0, 16, 0, 0, 0, 2, 0, 144]))
|
|
}
|
|
|
|
func testFromData() throws {
|
|
let sut = BloomFilter<String>(hashes: [.sdbm32, .djb232], data: Data([0, 16, 0, 0, 0, 2, 0, 144]))
|
|
|
|
XCTAssert(sut.contains("lol"))
|
|
XCTAssert(sut.contains("ok"))
|
|
XCTAssertFalse(sut.contains("wtf"))
|
|
XCTAssertFalse(sut.contains("no"))
|
|
}
|
|
|
|
func testCoding() throws {
|
|
var sut = BloomFilter<String>(hashes: [.sdbm32, .djb232], byteCount: 8)
|
|
let expectedData = Data(#"{"data":"ABAAAAACAJA=","hashes":["djb232","sdbm32"]}"#.utf8)
|
|
|
|
sut.insert("lol")
|
|
sut.insert("ok")
|
|
|
|
let encoder = JSONEncoder()
|
|
|
|
encoder.outputFormatting = .sortedKeys
|
|
|
|
let data = try encoder.encode(sut)
|
|
|
|
XCTAssertEqual(data, expectedData)
|
|
|
|
let decoded = try JSONDecoder().decode(BloomFilter<String>.self, from: data)
|
|
|
|
XCTAssert(decoded.contains("lol"))
|
|
XCTAssert(decoded.contains("ok"))
|
|
XCTAssertFalse(decoded.contains("wtf"))
|
|
XCTAssertFalse(decoded.contains("no"))
|
|
}
|
|
|
|
func testInvalidHash() throws {
|
|
let invalidData = Data(#"{"data":"ABAAAAACAJA=","hashes":["djb232","invalid"]}"#.utf8)
|
|
|
|
XCTAssertThrowsError(try JSONDecoder().decode(BloomFilter<String>.self, from: invalidData)) {
|
|
guard case DecodingError.dataCorrupted = $0 else {
|
|
XCTFail("Expected data corrupted error")
|
|
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func testDataEncodingStrategy() throws {
|
|
var sut = BloomFilter<String>(hashes: [.sdbm32, .djb232], byteCount: 8)
|
|
let expectedData = Data(#"{"data":"0010000000020090","hashes":["djb232","sdbm32"]}"#.utf8)
|
|
|
|
sut.insert("lol")
|
|
sut.insert("ok")
|
|
|
|
let encoder = JSONEncoder()
|
|
|
|
encoder.outputFormatting = .sortedKeys
|
|
encoder.dataEncodingStrategy = .custom { data, encoder in
|
|
var container = encoder.singleValueContainer()
|
|
|
|
try container.encode(data.map { String(format: "%02.2hhx", $0) }.joined())
|
|
}
|
|
|
|
let data = try encoder.encode(sut)
|
|
|
|
XCTAssertEqual(data, expectedData)
|
|
}
|
|
|
|
func testDataDecodingStrategy() throws {
|
|
let data = Data(#"{"data":"0010000000020090","hashes":["djb232","sdbm32"]}"#.utf8)
|
|
let decoder = JSONDecoder()
|
|
|
|
decoder.dataDecodingStrategy = .custom { decoder in
|
|
let container = try decoder.singleValueContainer()
|
|
let string = try container.decode(String.self)
|
|
var bytes = [UInt8]()
|
|
var i = string.startIndex
|
|
|
|
while i != string.endIndex {
|
|
let j = string.index(i, offsetBy: 2)
|
|
|
|
guard let byte = UInt8(string[i..<j], radix: 16) else {
|
|
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid byte")
|
|
}
|
|
|
|
bytes.append(byte)
|
|
i = j
|
|
}
|
|
|
|
return Data(bytes)
|
|
}
|
|
|
|
let sut = try decoder.decode(BloomFilter<String>.self, from: data)
|
|
|
|
XCTAssert(sut.contains("lol"))
|
|
XCTAssert(sut.contains("ok"))
|
|
XCTAssertFalse(sut.contains("wtf"))
|
|
XCTAssertFalse(sut.contains("no"))
|
|
}
|
|
}
|