LMAssembly // Updating Unit Tests.
This commit is contained in:
parent
4224509dae
commit
f81e6837b8
|
@ -1,5 +1,4 @@
|
|||
//// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||
// StringView Ranges extension by (c) 2022 and onwards Isaac Xen (MIT License).
|
||||
// ====================
|
||||
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
|
||||
// ... with NTL restriction stating that:
|
||||
|
@ -49,8 +48,8 @@ final class LMCassetteTests: XCTestCase {
|
|||
XCTAssertFalse(lmCassette.quickDefMap.isEmpty)
|
||||
print(lmCassette.quickSetsFor(key: ",.") ?? "")
|
||||
XCTAssertEqual(lmCassette.keyNameMap.count, 41)
|
||||
XCTAssertEqual(lmCassette.charDefMap.count, 29537)
|
||||
XCTAssertEqual(lmCassette.charDefWildcardMap.count, 11973)
|
||||
XCTAssertEqual(lmCassette.charDefMap.count, 29491)
|
||||
XCTAssertEqual(lmCassette.charDefWildcardMap.count, 11946)
|
||||
XCTAssertEqual(lmCassette.octagramMap.count, 0)
|
||||
XCTAssertEqual(lmCassette.octagramDividedMap.count, 0)
|
||||
XCTAssertEqual(lmCassette.nameShort, "AR30")
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
//// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||
// ====================
|
||||
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
|
||||
// ... with NTL restriction stating that:
|
||||
// No trademark license is granted to use the trade names, trademarks, service
|
||||
// marks, or product names of Contributor, except as required to fulfill notice
|
||||
// requirements defined in MIT License.
|
||||
|
||||
import Foundation
|
||||
import XCTest
|
||||
|
||||
@testable import LangModelAssembly
|
||||
|
||||
private let nowTimeStamp: Double = 114_514 * 10000
|
||||
private let capacity = 5
|
||||
private let halfLife: Double = 5400
|
||||
private let nullURL = URL(fileURLWithPath: "/dev/null")
|
||||
|
||||
final class LMUserOverrideTests: XCTestCase {
|
||||
private func observe(who uom: vChewingLM.LMUserOverride, key: String, candidate: String, timestamp stamp: Double) {
|
||||
uom.doObservation(key: key, candidate: candidate, timestamp: stamp, forceHighScoreOverride: false, saveCallback: {})
|
||||
}
|
||||
|
||||
func testUOM_1_BasicOps() throws {
|
||||
let uom = vChewingLM.LMUserOverride(capacity: capacity, decayConstant: Double(halfLife), dataURL: nullURL)
|
||||
let key = "((ㄍㄨㄥ-ㄙ,公司),(ㄉㄜ˙,的),ㄋㄧㄢˊ-ㄓㄨㄥ)"
|
||||
let headReading = "ㄋㄧㄢˊ-ㄓㄨㄥ"
|
||||
let expectedSuggestion = "年終"
|
||||
observe(who: uom, key: key, candidate: expectedSuggestion, timestamp: nowTimeStamp)
|
||||
var suggested = uom.getSuggestion(key: key, timestamp: nowTimeStamp, headReading: headReading)
|
||||
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", expectedSuggestion)
|
||||
var i = 0
|
||||
while !suggested.candidates.isEmpty {
|
||||
suggested = uom.getSuggestion(key: key, timestamp: nowTimeStamp + (halfLife * Double(i)), headReading: headReading)
|
||||
let suggestedCandidates = suggested.candidates
|
||||
if suggestedCandidates.isEmpty { print(i) }
|
||||
if i >= 21 {
|
||||
XCTAssertNotEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", expectedSuggestion, i.description)
|
||||
XCTAssert(suggested.candidates.isEmpty)
|
||||
} else {
|
||||
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", expectedSuggestion, i.description)
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
}
|
||||
|
||||
func testUOM_2_NewestAgainstRepeatedlyUsed() throws {
|
||||
let uom = vChewingLM.LMUserOverride(capacity: capacity, decayConstant: Double(halfLife), dataURL: nullURL)
|
||||
let key = "((ㄍㄨㄥ-ㄙ,公司),(ㄉㄜ˙,的),ㄋㄧㄢˊ-ㄓㄨㄥ)"
|
||||
let headReading = "ㄋㄧㄢˊ-ㄓㄨㄥ"
|
||||
let valRepeatedlyUsed = "年終" // 更常用
|
||||
let valNewest = "年中" // 最近偶爾用了一次
|
||||
let stamps: [Double] = [0, 0.5, 2, 2.5, 4, 4.5, 5.3].map { nowTimeStamp + halfLife * $0 }
|
||||
stamps.forEach { stamp in
|
||||
observe(who: uom, key: key, candidate: valRepeatedlyUsed, timestamp: stamp)
|
||||
}
|
||||
var suggested = uom.getSuggestion(key: key, timestamp: nowTimeStamp, headReading: headReading)
|
||||
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", valRepeatedlyUsed)
|
||||
[6.0, 18.0, 23.0].forEach { i in
|
||||
suggested = uom.getSuggestion(key: key, timestamp: nowTimeStamp + halfLife * Double(i), headReading: headReading)
|
||||
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", valRepeatedlyUsed, i.description)
|
||||
}
|
||||
// 試試看偶爾選了不常用的詞的話、是否會影響上文所生成的有一定強效的記憶。
|
||||
observe(who: uom, key: key, candidate: valNewest, timestamp: nowTimeStamp + halfLife * 23.4)
|
||||
suggested = uom.getSuggestion(key: key, timestamp: nowTimeStamp + halfLife * 23.6, headReading: headReading)
|
||||
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", valNewest)
|
||||
suggested = uom.getSuggestion(key: key, timestamp: nowTimeStamp + halfLife * 26, headReading: headReading)
|
||||
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", valNewest)
|
||||
suggested = uom.getSuggestion(key: key, timestamp: nowTimeStamp + halfLife * 50, headReading: headReading)
|
||||
XCTAssertNotEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", valNewest)
|
||||
XCTAssert(suggested.candidates.isEmpty)
|
||||
}
|
||||
|
||||
func testUOM_3_LRUTable() throws {
|
||||
let a = (key: "((ㄍㄨㄥ-ㄙ,公司),(ㄉㄜ˙,的),ㄋㄧㄢˊ-ㄓㄨㄥ)", value: "年終", head: "ㄋㄧㄢˊ-ㄓㄨㄥ")
|
||||
let b = (key: "((ㄑㄧˋ-ㄧㄝˋ,企業),(ㄉㄜ˙,的),ㄐㄧㄤˇ-ㄐㄧㄣ)", value: "獎金", head: "ㄐㄧㄤˇ-ㄐㄧㄣ")
|
||||
let c = (key: "((ㄒㄩㄝˊ-ㄕㄥ,學生),(ㄉㄜ˙,的),ㄈㄨˊ-ㄌㄧˋ)", value: "福利", head: "ㄈㄨˊ-ㄌㄧˋ")
|
||||
let d = (key: "((ㄌㄟˊ-ㄉㄧㄢˋ-ㄐㄧㄤ-ㄐㄩㄣ,雷電將軍),(ㄉㄜ˙,的),ㄐㄧㄠˇ-ㄔㄡˋ)", value: "腳臭", head: "ㄐㄧㄠˇ-ㄔㄡˋ")
|
||||
let uom = vChewingLM.LMUserOverride(capacity: 2, decayConstant: Double(halfLife), dataURL: nullURL)
|
||||
observe(who: uom, key: a.key, candidate: a.value, timestamp: nowTimeStamp)
|
||||
observe(who: uom, key: b.key, candidate: b.value, timestamp: nowTimeStamp + halfLife * 1)
|
||||
observe(who: uom, key: c.key, candidate: c.value, timestamp: nowTimeStamp + halfLife * 2)
|
||||
// C is in the list.
|
||||
var suggested = uom.getSuggestion(key: c.key, timestamp: nowTimeStamp + halfLife * 3, headReading: c.head)
|
||||
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", c.value)
|
||||
// B is in the list.
|
||||
suggested = uom.getSuggestion(key: b.key, timestamp: nowTimeStamp + halfLife * 3.5, headReading: b.head)
|
||||
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", b.value)
|
||||
// A is purged.
|
||||
suggested = uom.getSuggestion(key: a.key, timestamp: nowTimeStamp + halfLife * 4, headReading: a.head)
|
||||
XCTAssertNotEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", a.value)
|
||||
XCTAssert(suggested.candidates.isEmpty)
|
||||
// Observe a new pair (D).
|
||||
observe(who: uom, key: d.key, candidate: d.value, timestamp: nowTimeStamp + halfLife * 4.5)
|
||||
// D is in the list.
|
||||
suggested = uom.getSuggestion(key: d.key, timestamp: nowTimeStamp + halfLife * 5, headReading: d.head)
|
||||
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", d.value)
|
||||
// C is in the list.
|
||||
suggested = uom.getSuggestion(key: c.key, timestamp: nowTimeStamp + halfLife * 5.5, headReading: c.head)
|
||||
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", c.value)
|
||||
// B is purged.
|
||||
suggested = uom.getSuggestion(key: b.key, timestamp: nowTimeStamp + halfLife * 6, headReading: b.head)
|
||||
XCTAssertNotEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", b.value)
|
||||
XCTAssert(suggested.candidates.isEmpty)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue