Mutation pins for context.rs and encode.rs: empty train, uncited speaker, nested mark

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Weksa 2026-11-13 23:51:11 +00:00
commit 5b36198577
5 changed files with 100 additions and 0 deletions

View file

@ -759,6 +759,9 @@ impl Prompt {
}
}
#[cfg(test)]
mod mutants;
#[cfg(test)]
mod tests {
use super::*;

View file

@ -0,0 +1,14 @@
//! Pins for private reach of `context.rs` that no run can produce.
use super::*;
/// A corpus with no live Train item of the panel's languages holds an empty
/// train. (A run refuses a panel without Train items at open, so only the
/// builder shows it.)
#[test]
fn no_train_item_of_the_panel_is_an_empty_train() {
let dir = tempfile::tempdir().unwrap();
let corpus = CorpusStore::open(&dir.path().join("c.cc")).unwrap();
let train = TrainItems::from_corpus(&corpus, &["en-US".to_string()]).unwrap();
assert_eq!((train.len(), train.is_empty()), (0, true));
}

View file

@ -566,6 +566,9 @@ pub fn packet_id(item: &CorpusItemId, rev: u32, encoder: &EncoderId) -> PacketId
PacketId::parse(&format!("packet:{}", hex16(digest))).expect("a packet id is well formed")
}
#[cfg(test)]
mod mutants;
#[cfg(test)]
mod tests {
use super::*;

View file

@ -0,0 +1,13 @@
//! Pins for `unmark` that the import door only reaches through a whole work.
use super::*;
/// A form that opens another markup is malformed, though its entity id is
/// sound: the model wrote a nested or unclosed mark, not a name.
#[test]
fn a_form_that_opens_a_mark_is_malformed() {
assert_eq!(unmark("[[entity:orsa|Or[[sa]] came"), None);
// The same line without the nested opener unmarks.
let (plain, names) = unmark("[[entity:orsa|Orsa]] came").unwrap();
assert_eq!((plain.as_str(), names.len()), ("Orsa came", 1));
}

View file

@ -0,0 +1,67 @@
//! Pins for behaviour of `context.rs`, `encode.rs` and `run.rs` found unpinned
//! by mutation testing. Each test states what the code does in domain terms.
mod common;
use std::path::{Path, PathBuf};
use weksa::context::Prompt;
use weksa::entity::{Entity, EntityOrigin, LanguageForms};
use weksa::packet::{EntityId, proof_packet};
use weksa::{CorpusItemId, CorpusStore, EntityForms, EntityStore, InventoryStore, PacketStore};
fn data(sub: &str) -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).join("../../data").join(sub)
}
struct Held(Vec<Entity>);
impl EntityForms for Held {
fn entity(&self, id: &EntityId) -> anyhow::Result<Option<Entity>> {
Ok(self.0.iter().find(|e| &e.id == id).cloned())
}
}
fn spoken(slug: &str, form: &str) -> Entity {
Entity {
id: EntityId::parse(&format!("entity:{slug}")).unwrap(),
forms: vec![LanguageForms {
language: "en-US".into(),
forms: vec![form.into()],
pronunciation: None,
}],
origin: EntityOrigin::Cast { persona: slug.into(), fixture: "f.yaml".into() },
}
}
/// A speaker whom no referent cites contributes no entry to the lowering
/// prompt, even when another entity is cited: only the cited entity is listed.
#[test]
fn an_uncited_speaker_is_absent_from_the_lowering_prompt() {
let cast_inv = InventoryStore::open(&data("interlingua/inventory.cc")).unwrap();
let entities = EntityStore::open(&data("entity/entity.cc")).unwrap();
let corpus = CorpusStore::open(&data("corpus/corpus.cc")).unwrap();
let dir = tempfile::tempdir().unwrap();
let view = PacketStore::open(&dir.path().join("p.cc"))
.unwrap()
.admit(proof_packet(), &cast_inv, &corpus, &entities)
.unwrap();
let state = weksa::SpeakerStateStore::open(&dir.path().join("s.cc")).unwrap();
let view = view.with_scene(&cast_inv.inventory().unwrap(), &state, &corpus).unwrap();
let held = Held(vec![spoken("nibu", "Nibu"), spoken("other", "SPEAKERCANARY")]);
let item = CorpusItemId::parse("item:nibu:1").unwrap();
let speaker = EntityId::parse("entity:other").unwrap();
let prompt = Prompt::lower(
&view,
&item,
&speaker,
"en-US",
&cast_inv.inventory().unwrap(),
&held,
&weksa::Ontology::empty(),
)
.unwrap();
let text = prompt.text();
assert!(text.contains("\n\nentities: {\"entity:nibu\":[\"Nibu\"]}\n\n"), "{text}");
assert!(!text.contains("SPEAKERCANARY"), "{text}");
}