@jarcelao/pi-exa-api 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,216 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import {
3
+ formatSearchResults,
4
+ formatFetchResult,
5
+ formatCodeContextResult,
6
+ parseCostDollars,
7
+ } from "../extensions/index.ts";
8
+
9
+ describe("formatSearchResults", () => {
10
+ it("should format basic result fields", () => {
11
+ const formatted = formatSearchResults({
12
+ results: [
13
+ {
14
+ title: "Test Article",
15
+ url: "https://example.com/article",
16
+ publishedDate: "2024-01-15",
17
+ author: "John Doe",
18
+ },
19
+ ],
20
+ });
21
+ expect(formatted).toContain("--- Result 1 ---");
22
+ expect(formatted).toContain("Title: Test Article");
23
+ expect(formatted).toContain("URL: https://example.com/article");
24
+ expect(formatted).toContain("Published: 2024-01-15");
25
+ expect(formatted).toContain("Author: John Doe");
26
+ });
27
+
28
+ it("should omit publishedDate and author when null", () => {
29
+ const formatted = formatSearchResults({
30
+ results: [{ title: "Test", url: "https://example.com", publishedDate: null, author: null }],
31
+ });
32
+ expect(formatted).toContain("Title: Test");
33
+ expect(formatted).not.toContain("Published:");
34
+ expect(formatted).not.toContain("Author:");
35
+ });
36
+
37
+ it("should format highlights with bullet points", () => {
38
+ const formatted = formatSearchResults({
39
+ results: [
40
+ {
41
+ title: "Test",
42
+ url: "https://example.com",
43
+ highlights: ["First highlight", "Second highlight"],
44
+ },
45
+ ],
46
+ });
47
+ expect(formatted).toContain("Highlights:");
48
+ expect(formatted).toContain(" • First highlight");
49
+ expect(formatted).toContain(" • Second highlight");
50
+ });
51
+
52
+ it("should format summary inline", () => {
53
+ const formatted = formatSearchResults({
54
+ results: [{ title: "Test", url: "https://example.com", summary: "This is a summary" }],
55
+ });
56
+ expect(formatted).toContain("Summary: This is a summary");
57
+ });
58
+
59
+ it("should truncate text preview to 500 characters", () => {
60
+ const longText = "a".repeat(600);
61
+ const formatted = formatSearchResults({
62
+ results: [{ title: "Test", url: "https://example.com", text: longText }],
63
+ });
64
+ expect(formatted).toContain("a".repeat(500));
65
+ expect(formatted).toContain("...");
66
+ expect(formatted).not.toContain("a".repeat(501));
67
+ });
68
+
69
+ it("should not append ellipsis for short text", () => {
70
+ const formatted = formatSearchResults({
71
+ results: [{ title: "Test", url: "https://example.com", text: "short" }],
72
+ });
73
+ expect(formatted).toContain("Text: short");
74
+ expect(formatted).not.toContain("short...");
75
+ });
76
+
77
+ it("should include cost when provided", () => {
78
+ const formatted = formatSearchResults({
79
+ results: [{ title: "Test", url: "https://example.com" }],
80
+ costDollars: { total: 0.000123 },
81
+ });
82
+ expect(formatted).toContain("Cost: $0.000123");
83
+ });
84
+
85
+ it("should omit cost line when not provided", () => {
86
+ const formatted = formatSearchResults({
87
+ results: [{ title: "Test", url: "https://example.com" }],
88
+ });
89
+ expect(formatted).not.toContain("Cost:");
90
+ });
91
+
92
+ it("should number multiple results sequentially", () => {
93
+ const formatted = formatSearchResults({
94
+ results: [
95
+ { title: "First", url: "https://a.com" },
96
+ { title: "Second", url: "https://b.com" },
97
+ { title: "Third", url: "https://c.com" },
98
+ ],
99
+ });
100
+ expect(formatted).toContain("--- Result 1 ---");
101
+ expect(formatted).toContain("--- Result 2 ---");
102
+ expect(formatted).toContain("--- Result 3 ---");
103
+ });
104
+ });
105
+
106
+ describe("formatFetchResult", () => {
107
+ it("should format text content", () => {
108
+ const formatted = formatFetchResult(
109
+ { title: "Page Title", url: "https://example.com", text: "Full page content" },
110
+ "text",
111
+ );
112
+ expect(formatted).toContain("Title: Page Title");
113
+ expect(formatted).toContain("Full page content");
114
+ });
115
+
116
+ it("should format highlights with bullet points", () => {
117
+ const formatted = formatFetchResult(
118
+ { title: "Test", url: "https://example.com", highlights: ["Key point 1", "Key point 2"] },
119
+ "highlights",
120
+ );
121
+ expect(formatted).toContain("Highlights:");
122
+ expect(formatted).toContain(" • Key point 1");
123
+ expect(formatted).toContain(" • Key point 2");
124
+ });
125
+
126
+ it("should format summary", () => {
127
+ const formatted = formatFetchResult(
128
+ { title: "Test", url: "https://example.com", summary: "This page is about..." },
129
+ "summary",
130
+ );
131
+ expect(formatted).toContain("Summary:");
132
+ expect(formatted).toContain("This page is about...");
133
+ });
134
+
135
+ it("should omit title when not provided", () => {
136
+ const formatted = formatFetchResult(
137
+ { url: "https://example.com", text: "Content only" } as Parameters<
138
+ typeof formatFetchResult
139
+ >[0],
140
+ "text",
141
+ );
142
+ expect(formatted).toContain("URL: https://example.com");
143
+ expect(formatted).not.toContain("Title:");
144
+ });
145
+
146
+ it("should handle empty highlights array", () => {
147
+ const formatted = formatFetchResult(
148
+ { title: "Test", url: "https://example.com", highlights: [] },
149
+ "highlights",
150
+ );
151
+ expect(formatted).toContain("URL: https://example.com");
152
+ expect(formatted).not.toContain("Highlights:");
153
+ });
154
+
155
+ it("should handle missing text for text contentType", () => {
156
+ const formatted = formatFetchResult({ title: "Test", url: "https://example.com" }, "text");
157
+ expect(formatted).toContain("URL: https://example.com");
158
+ // No text section should appear
159
+ expect(formatted).not.toContain("Text:");
160
+ });
161
+ });
162
+
163
+ describe("parseCostDollars", () => {
164
+ it("should parse JSON string costDollars", () => {
165
+ const parsed = parseCostDollars('{"total":0.007,"search":{"neural":0.007}}');
166
+ expect(parsed).toEqual({ total: 0.007, search: { neural: 0.007 } });
167
+ });
168
+
169
+ it("should pass through object costDollars unchanged", () => {
170
+ const costObject = { total: 1.5 };
171
+ expect(parseCostDollars(costObject)).toBe(costObject);
172
+ });
173
+
174
+ it("should handle zero cost", () => {
175
+ expect(parseCostDollars('{"total":0}').total).toBe(0);
176
+ });
177
+ });
178
+
179
+ describe("formatCodeContextResult", () => {
180
+ const baseResponse = {
181
+ requestId: "req_123",
182
+ query: "React hooks state management",
183
+ response: "## Example\n\n```js\nconst [count, setCount] = useState(0);\n```",
184
+ resultsCount: 502,
185
+ costDollars: '{"total":0.007}',
186
+ searchTime: 1.234,
187
+ outputTokens: 4805,
188
+ };
189
+
190
+ it("should include all key fields", () => {
191
+ const formatted = formatCodeContextResult(baseResponse);
192
+ expect(formatted).toContain("Query: React hooks state management");
193
+ expect(formatted).toContain("Results: 502 sources");
194
+ expect(formatted).toContain("Output tokens: 4805");
195
+ expect(formatted).toContain("--- Code Context ---");
196
+ expect(formatted).toContain("## Example");
197
+ });
198
+
199
+ it("should format cost from JSON string", () => {
200
+ const formatted = formatCodeContextResult(baseResponse);
201
+ expect(formatted).toContain("Cost: $0.007000");
202
+ });
203
+
204
+ it("should format cost from object", () => {
205
+ const formatted = formatCodeContextResult({ ...baseResponse, costDollars: { total: 1.5 } });
206
+ expect(formatted).toContain("Cost: $1.500000");
207
+ });
208
+
209
+ it("should format cost with full decimal precision", () => {
210
+ const formatted = formatCodeContextResult({
211
+ ...baseResponse,
212
+ costDollars: '{"total":0.123456}',
213
+ });
214
+ expect(formatted).toContain("Cost: $0.123456");
215
+ });
216
+ });