using ClaudeDo.Data; using Xunit; namespace ClaudeDo.Data.Tests; public class TaskPromptComposerTests { [Fact] public void Composes_title_description_and_open_steps() { var result = TaskPromptComposer.Compose( "Refactor diff viewer", "Share the row template.", new (string, bool)[] { ("Done step", true), ("Open step", false) }); Assert.Equal( "Refactor diff viewer\n\nShare the row template.\n\n## Sub-Tasks\n- [ ] Open step\n", result); } [Fact] public void Drops_resolved_steps_and_omits_section_when_none_open() { var result = TaskPromptComposer.Compose( "Title", "Desc", new (string, bool)[] { ("a", true), ("b", true) }); Assert.Equal("Title\n\nDesc", result); } [Fact] public void Omits_description_when_blank() { var result = TaskPromptComposer.Compose("Title", " ", new (string, bool)[] { ("open", false) }); Assert.Equal("Title\n\n## Sub-Tasks\n- [ ] open\n", result); } [Fact] public void Title_only_when_no_description_or_steps() { Assert.Equal("Just a title", TaskPromptComposer.Compose("Just a title", null, System.Array.Empty<(string, bool)>())); } [Fact] public void Attachment_section_present_when_paths_given() { var result = TaskPromptComposer.Compose( "Title", null, System.Array.Empty<(string, bool)>(), new[] { "/a/b/file1.txt", "/a/b/file2.txt" }); Assert.Contains("## Reference files", result); Assert.Contains("- /a/b/file1.txt", result); Assert.Contains("- /a/b/file2.txt", result); } [Fact] public void Attachment_section_absent_when_null() { var result = TaskPromptComposer.Compose("Title", null, System.Array.Empty<(string, bool)>(), null); Assert.DoesNotContain("Reference files", result); } [Fact] public void Attachment_section_absent_when_empty() { var result = TaskPromptComposer.Compose("Title", null, System.Array.Empty<(string, bool)>(), System.Array.Empty()); Assert.DoesNotContain("Reference files", result); } [Fact] public void Attachment_paths_order_preserved() { var paths = new[] { "/z/last.txt", "/a/first.txt", "/m/middle.txt" }; var result = TaskPromptComposer.Compose("Title", null, System.Array.Empty<(string, bool)>(), paths); var idxZ = result.IndexOf("/z/last.txt", StringComparison.Ordinal); var idxA = result.IndexOf("/a/first.txt", StringComparison.Ordinal); var idxM = result.IndexOf("/m/middle.txt", StringComparison.Ordinal); Assert.True(idxZ < idxA && idxA < idxM, "Paths should appear in the original order."); } }