From d41eaa6504feef7f2875206310f2d48f58bd2a45 Mon Sep 17 00:00:00 2001 From: prosolis <5590409+prosolis@users.noreply.github.com> Date: Fri, 22 May 2026 18:31:26 -0700 Subject: [PATCH] Test bullet parser; fix marker-less passthrough MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous parser treated any non-empty non-header line as a bullet, so 'plain paragraph' answers were silently rewrapped as
as originally intended.
Tests cover dash/asterisk/unicode bullets, blank-line tolerance,
Summary:/TL;DR header stripping, HTML escaping, single-bullet output,
the no-marker passthrough path, and the IsQuestionReaction set.
---
internal/explainer/explainer.go | 23 ++++--
internal/explainer/explainer_test.go | 110 +++++++++++++++++++++++++++
2 files changed, 125 insertions(+), 8 deletions(-)
create mode 100644 internal/explainer/explainer_test.go
diff --git a/internal/explainer/explainer.go b/internal/explainer/explainer.go
index bc70da0..40840d5 100644
--- a/internal/explainer/explainer.go
+++ b/internal/explainer/explainer.go
@@ -139,29 +139,36 @@ func (e *Explainer) summarize(headline, body string) (string, error) {
func formatSummary(raw string) (plain, htmlBody string) {
lines := strings.Split(raw, "\n")
var bullets []string
+ sawMarker := false
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" {
continue
}
- // Normalize common bullet markers
- for _, prefix := range []string{"- ", "* ", "• ", "·"} {
- if strings.HasPrefix(line, prefix) {
- line = strings.TrimSpace(line[len(prefix):])
- break
- }
- }
// Skip header-ish lines the model sometimes adds
low := strings.ToLower(line)
if strings.HasPrefix(low, "summary:") || strings.HasPrefix(low, "tl;dr") {
continue
}
+ // Normalize common bullet markers; only count this line if it had one.
+ hadMarker := false
+ for _, prefix := range []string{"- ", "* ", "• ", "·"} {
+ if strings.HasPrefix(line, prefix) {
+ line = strings.TrimSpace(line[len(prefix):])
+ hadMarker = true
+ break
+ }
+ }
+ if !hadMarker {
+ continue
+ }
+ sawMarker = true
if line == "" {
continue
}
bullets = append(bullets, line)
}
- if len(bullets) == 0 {
+ if !sawMarker || len(bullets) == 0 {
// Model produced something but we couldn't parse bullets — pass through.
return raw, "" + html.EscapeString(raw) + "
"
}
diff --git a/internal/explainer/explainer_test.go b/internal/explainer/explainer_test.go
new file mode 100644
index 0000000..4d1b5d4
--- /dev/null
+++ b/internal/explainer/explainer_test.go
@@ -0,0 +1,110 @@
+package explainer
+
+import (
+ "strings"
+ "testing"
+)
+
+func TestFormatSummary(t *testing.T) {
+ cases := []struct {
+ name string
+ in string
+ wantPlain string
+ wantHTML string
+ }{
+ {
+ name: "dash bullets",
+ in: "- First point.\n- Second point.\n- Third point.",
+ wantPlain: "• First point.\n• Second point.\n• Third point.",
+ wantHTML: "") || !strings.HasSuffix(htmlBody, "") { + t.Errorf("html should wrap raw in
, got %q", htmlBody)
+ }
+ if !strings.Contains(htmlBody, "single paragraph") {
+ t.Errorf("html should contain the body text, got %q", htmlBody)
+ }
+}
+
+func TestIsQuestionReaction(t *testing.T) {
+ want := []string{"❓", "❔", "⁉", "⁉️", "🤔", "?", "?"}
+ for _, k := range want {
+ if !IsQuestionReaction(k) {
+ t.Errorf("expected %q to trigger explain", k)
+ }
+ }
+ notQuestion := []string{"👍", "👎", "🔥", "", "??", "❤️"}
+ for _, k := range notQuestion {
+ if IsQuestionReaction(k) {
+ t.Errorf("expected %q to NOT trigger explain", k)
+ }
+ }
+}