Assert.That(passages.Select(passage=>passage.Text),Is.EqualTo(new[]{"The mixing console.","The amplifier."}),"Two searches for one answer may find the same chunk, but the AI read it once.");
Assert.That(passages.Select(passage=>passage.SourceUrl),Is.EqualTo(new[]{$"{HANDBOOK_URL}#page=3",$"{HANDBOOK_URL}#page=12"}),"A heading repeated on every page is a passage of each of them.");
Assert.That(found.Select(passage=>passage.Text),Is.EqualTo(new[]{"The mixing console.","The equalizer."}),"The list keeps one entry per document, so that entry stands for all of its pages, and for nothing else.");
Assert.That(label,Does.Contain("1, 4–5, 11"),"Each page once, ranges as ranges, in the order of the document; a passage without a page adds nothing.");
Assert.That(new[]{Passage(HANDBOOK_URL,"A.",pageNumber:3),Passage(HANDBOOK_URL,"B.",pageNumber:3)}.GetLocationLabel(),Is.EqualTo(Passage(HANDBOOK_URL,"A.",pageNumber:3).GetLocationLabel()),"Two passages on one page name one page.");
Assert.That(location!.Ranges,Is.EqualTo(new[]{newLocationRange(1,2),newLocationRange(11,11)}),"Each page range becomes a link of its own, in the order of the document.");
Assert.That(location.ArePages,Is.True);
Assert.That(location.ToString(),Is.EqualTo($"{location.Prefix}1–2, 11{location.Suffix}"),"The links read the same as the title of the source.");
Assert.That(new[]{Passage(HANDBOOK_URL,"A slide.")}.GetLocation(),Is.Null,"Where the data source says neither pages nor parts, nothing is invented.");
Assert.That(location!.Ranges,Is.EqualTo(new[]{newLocationRange(2,2),newLocationRange(5,5)}),"The parts follow the order of the document.");
Assert.That(location.ArePages,Is.False,"A part is nothing a program can open a document at, so it becomes no link.");
Assert.That(location.ToString(),Is.Not.EqualTo(new[]{Passage(MANUAL_URL,"Step two.",pageNumber:2),Passage(MANUAL_URL,"Step five.",pageNumber:5)}.GetLocationLabel()),"Parts are not called pages.");
Assert.That(new[]{Passage(MANUAL_URL,"Step two.",pageNumber:7,chunkNumber:2)}.GetLocation()!.Ranges,Is.EqualTo(new[]{newLocationRange(7,7)}),"Where there are pages, they say better where a passage is.");
Assert.That(location!.Ranges,Is.EqualTo(new[]{newLocationRange(40,85),newLocationRange(120,120)}),"The lines follow the order of the document, and a line range stays a range.");
Assert.That(location.ArePages,Is.False,"No program can be told to open a document at a line, so a line becomes no link.");
Assert.That(rows.GetLocationLabel(),Is.Not.EqualTo((rowswith{StartRow=null,EndRow=null,StartLine=12,EndLine=30}).GetLocationLabel()),"Rows are not called lines.");
Assert.That((Passage(MANUAL_URL,"Later.",chunkNumber:120)with{StartLine=120}).GetLocationLabel(),Is.Not.EqualTo(Passage(MANUAL_URL,"Later.",chunkNumber:120).GetLocationLabel()),"Lines are not called parts.");
Assert.That(new[]{lines[1]with{PageNumber=3}}.GetLocation()!.ArePages,Is.True,"Where there are pages, they say better where a passage is.");
Assert.That(label,Does.Contain("Budget").And.Contain("3–9, 20").And.Contain("Summary"),"Each sheet with its rows, each row once, in the order of the document.");
Assert.That(label.IndexOf("Budget",StringComparison.Ordinal),Is.LessThan(label.IndexOf("Summary",StringComparison.Ordinal)),"The sheets follow the order of the document.");
Assert.That(label.IndexOf("Budget",StringComparison.Ordinal),Is.EqualTo(label.LastIndexOf("Budget",StringComparison.Ordinal)),"A sheet is named once.");
Assert.That(Passage(MANUAL_URL,"Step three.",chunkNumber:3).GetLocationRange(),Is.EqualTo(newLocationRange(3,3)),"The dialog orders the passages of a text file by their parts.");
Assert.That(sources[0].Title,Is.EqualTo($"Handbooks ({passages.GetLocationLabel()})"),"The page of the second passage would otherwise go unmentioned.");
Assert.That(onePassage[0].Title,Is.EqualTo("Wiki"),"One passage keeps the title its data source gave it.");
Assert.That(twoPassages[0].Title,Does.StartWith("Handbooks (").And.Contain("2"),"Two passages under one title are counted, so the user knows to look for both.");
Assert.That(storedPassage.EnumerateObject().Select(property=>property.Name),Is.EquivalentTo(new[]{"source_url","data_source_name","path","category","type","text","surrounding_content","page_number","end_page_number","chunk_number"}),"A computed property would end up in every chat file as well.");
Assert.That(storedPassage.GetProperty("type").GetString(),Is.EqualTo("TEXT_DOCUMENT"),"The type is stored by name, so a type added later does not shift the stored ones.");
varoriginal=newContentText{Text="The console has 24 channels.",SourcePassages=[Passage(HANDBOOK_URL,"The mixing console.")]};
varcopy=(ContentText)original.DeepClone();
original.SourcePassages.Clear();
Assert.That(copy.SourcePassages.Select(passage=>passage.Text),Is.EqualTo(new[]{"The mixing console."}),"A copy which shares the list with its original loses its passages along with it.");