describe_test.go raw
1 package describe
2
3 import (
4 "strings"
5 "testing"
6 )
7
8 func TestExtractGoSource_SingleBlock(t *testing.T) {
9 answer := "Here's the code:\n\n```go\npackage main\n\nfunc main() {}\n```\n\nThat should work."
10 got := ExtractGoSource(answer)
11 if !strings.HasPrefix(got, "package main") {
12 t.Errorf("expected package main, got: %q", got)
13 }
14 if !strings.Contains(got, "func main()") {
15 t.Errorf("expected func main(), got: %q", got)
16 }
17 }
18
19 func TestExtractGoSource_MultipleBlocks(t *testing.T) {
20 answer := "Short example:\n```go\npackage p\n```\n\nFull code:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tfmt.Println(\"hello\")\n}\n```\n"
21 got := ExtractGoSource(answer)
22 // Should return the longer block.
23 if !strings.Contains(got, "fmt.Println") {
24 t.Errorf("expected longer block with fmt.Println, got: %q", got)
25 }
26 }
27
28 func TestExtractGoSource_NoBlocks(t *testing.T) {
29 // When response has no code blocks but starts with "package".
30 answer := "package main\n\nfunc main() {}\n"
31 got := ExtractGoSource(answer)
32 if !strings.HasPrefix(got, "package main") {
33 t.Errorf("expected raw source fallback, got: %q", got)
34 }
35 }
36
37 func TestExtractGoSource_Empty(t *testing.T) {
38 got := ExtractGoSource("No code here at all.")
39 if got != "" {
40 t.Errorf("expected empty, got: %q", got)
41 }
42 }
43
44 func TestExtractGoSource_PlainBackticks(t *testing.T) {
45 answer := "Here:\n```\npackage main\n\nfunc main() {}\n```\n"
46 got := ExtractGoSource(answer)
47 if !strings.HasPrefix(got, "package main") {
48 t.Errorf("expected fallback to plain backticks, got: %q", got)
49 }
50 }
51
52 func TestComposeCodeQuery_ContainsDescription(t *testing.T) {
53 desc := Description{Text: "Add a function named Foo that returns 42"}
54 query := ComposeCodeQuery(desc, "Types: Bar\nFunctions: Baz\n")
55 if !strings.Contains(query, "Foo") {
56 t.Error("query should contain the function name from description")
57 }
58 if !strings.Contains(query, "Bar") {
59 t.Error("query should contain self-knowledge type")
60 }
61 if !strings.Contains(query, "Baz") {
62 t.Error("query should contain self-knowledge function")
63 }
64 }
65
66 func TestComposeCodeQuery_WithTargetPkg(t *testing.T) {
67 desc := Description{Text: "some code", TargetPkg: "lattice"}
68 query := ComposeCodeQuery(desc, "")
69 if !strings.Contains(query, "package lattice") {
70 t.Error("query should mention target package")
71 }
72 }
73
74 func TestExtractExpectedNames(t *testing.T) {
75 tests := []struct {
76 desc string
77 expected []string
78 }{
79 {"Add a function named CountNodes that returns int", []string{"CountNodes"}},
80 {"Define a type called Summary with fields", []string{"Summary"}},
81 {"Create a function Foo that does something and a type Bar", []string{"Foo", "Bar"}},
82 {"Add a method named Process", []string{"Process"}},
83 {"No names here", nil},
84 }
85
86 for _, tt := range tests {
87 got := extractExpectedNames(tt.desc)
88 if len(got) != len(tt.expected) {
89 t.Errorf("desc=%q: got %v, want %v", tt.desc, got, tt.expected)
90 continue
91 }
92 for i := range got {
93 if got[i] != tt.expected[i] {
94 t.Errorf("desc=%q: got[%d]=%q, want %q", tt.desc, i, got[i], tt.expected[i])
95 }
96 }
97 }
98 }
99
100 func TestExtractDeclarations(t *testing.T) {
101 src := `package main
102
103 type Foo struct{}
104 type Bar interface{}
105
106 func Baz() {}
107 func (f Foo) Qux() {}
108 `
109 decls := extractDeclarations(src)
110 expected := map[string]bool{
111 "package:main": true,
112 "type:Foo": true,
113 "type:Bar": true,
114 "func:Baz": true,
115 "method:Qux": true,
116 }
117
118 got := make(map[string]bool)
119 for _, d := range decls {
120 got[d] = true
121 }
122
123 for k := range expected {
124 if !got[k] {
125 t.Errorf("missing declaration: %s", k)
126 }
127 }
128 }
129
130 func TestExtractSelfKnowledge_Nil(t *testing.T) {
131 got := ExtractSelfKnowledge(nil)
132 if got != "" {
133 t.Errorf("expected empty for nil lattice, got: %q", got)
134 }
135 }
136
137 func TestJoinKeys(t *testing.T) {
138 m := map[string]bool{"c": true, "a": true, "b": true}
139 got := joinKeys(m)
140 if got != "a, b, c" {
141 t.Errorf("expected sorted keys, got: %q", got)
142 }
143 }
144