70 lines
3.7 KiB
Go
70 lines
3.7 KiB
Go
package main
|
||
|
||
import (
|
||
"strings"
|
||
"testing"
|
||
|
||
"textmachine/backend/internal/pipeline"
|
||
)
|
||
|
||
// main_test.go pins the two rules this probe got WRONG before it got them right. Both produced numbers
|
||
// that looked reasonable, which is the only reason they needed a test: a measurement instrument fails by
|
||
// reporting, not by crashing.
|
||
|
||
// TestARowTheBankSettledIsInNeitherDenominator. The settled filter runs BEFORE the first paid call, so a
|
||
// row it removed is neither «a candidate at the role's input» nor «a row the role answered». The first
|
||
// version of this probe kept it on the pre-call side only: the two denominators then differed by a row
|
||
// that reached neither, and every pre-call share was quietly diluted.
|
||
func TestARowTheBankSettledIsInNeitherDenominator(t *testing.T) {
|
||
s := &source{rows: []pipeline.BankStopRow{
|
||
{Src: "方源", Dst: "", SettledByBank: true}, // settled: in neither
|
||
{Src: "花家", Dst: ""}, // answered with nothing: in the pre-call one only
|
||
{Src: "青茅山", Dst: "гора Цинмао"}, // an ordinary answered row
|
||
{Src: "丙等", Dst: "третий разряд"}, //
|
||
}}
|
||
pre, answered, settled, unresolved := s.denominators()
|
||
if pre != 3 || answered != 2 || settled != 1 || unresolved != 1 {
|
||
t.Errorf("denominators = pre %d, answered %d, settled %d, unresolved %d; want 3, 2, 1, 1", pre, answered, settled, unresolved)
|
||
}
|
||
}
|
||
|
||
// TestTheComparedInputNeverCarriesTheAnswer is the other one, and it is the more dangerous: the §4.4
|
||
// comparison asks «did the row's INPUT change where the decision changed», so folding the consolidated
|
||
// rendering into the input makes the answer «the input changed» for every row whose answer changed — 100 %
|
||
// of the population, by construction, with nothing red anywhere. That is what the first version did (it
|
||
// read the signature map's note, which names the top proposal's chunk COUNT but not its text, so the
|
||
// rendering had to be substituted for it).
|
||
func TestTheComparedInputNeverCarriesTheAnswer(t *testing.T) {
|
||
before := pipeline.BankStopRow{
|
||
Src: "熊家寨", Dst: "селение Сюн", Type: "place", Origin: "banknote", Freq: 4, Conf: 85,
|
||
Variants: []pipeline.BankStopVariant{{Dst: "селение Сюн", Chunks: 1}},
|
||
Contexts: []string{"一段"},
|
||
}
|
||
after := before
|
||
after.Dst = "крепость рода Сюн" // the ANSWER moved
|
||
after.Conf = 60 // and so did the role's own confidence
|
||
after.Invented = true // and the invented mark, which is also an output
|
||
if rowInput(before, true) != rowInput(after, true) {
|
||
t.Errorf("a row whose ANSWER moved and whose input did not must compare EQUAL:\n before: %s\n after : %s",
|
||
rowInput(before, true), rowInput(after, true))
|
||
}
|
||
// And a row whose input really moved must NOT compare equal — otherwise the test above would pass on a
|
||
// function that returns a constant.
|
||
moved := before
|
||
moved.Variants = []pipeline.BankStopVariant{{Dst: "крепость рода Сюн", Chunks: 2}}
|
||
if rowInput(before, true) == rowInput(moved, true) {
|
||
t.Error("a row whose draft proposals moved must compare DIFFERENT")
|
||
}
|
||
// The contexts are part of the input, and they are what the earlier instrument could not see at all.
|
||
ctxMoved := before
|
||
ctxMoved.Contexts = []string{"другой контекст"}
|
||
if rowInput(before, true) == rowInput(ctxMoved, true) {
|
||
t.Error("a row whose source contexts moved must compare DIFFERENT when contexts are included")
|
||
}
|
||
if rowInput(before, false) != rowInput(ctxMoved, false) {
|
||
t.Error("and must compare EQUAL when they are not — the two questions are asked separately on purpose")
|
||
}
|
||
if !strings.Contains(rowInput(before, false), "drafts=[") {
|
||
t.Errorf("the compared input must name the drafts it compared: %s", rowInput(before, false))
|
||
}
|
||
}
|