f051cc6a0e
- Added support for multi-range line selectors on URLs (e.g., `:5-10,20-30`) and combining `:raw` mode with line range selectors. - Added support for line range selectors on directory listings with offset and limit parameters. - Fixed `:raw` selector being ignored for JSON and feed URLs and directory listing line selectors dropping offset parameter. - Added clear error message for line offset beyond directory listing end. - Refactored URL parsing and directory reading to support multiple comma-separated ranges and improved line-based slicing logic. - Added comprehensive test coverage for multi-range selectors, raw mode combinations, and directory range operations.
107 lines
3.3 KiB
TypeScript
107 lines
3.3 KiB
TypeScript
import { describe, expect, it } from "bun:test";
|
|
import { parseReadUrlTarget } from "@oh-my-pi/pi-coding-agent/tools/fetch";
|
|
|
|
describe("parseReadUrlTarget", () => {
|
|
it("returns null for non-URL paths", () => {
|
|
expect(parseReadUrlTarget("/etc/hosts")).toBeNull();
|
|
expect(parseReadUrlTarget("relative/file.ts")).toBeNull();
|
|
});
|
|
|
|
it("returns a bare URL with no selectors", () => {
|
|
expect(parseReadUrlTarget("https://example.com/foo")).toEqual({
|
|
path: "https://example.com/foo",
|
|
raw: false,
|
|
});
|
|
});
|
|
|
|
it("peels :raw", () => {
|
|
expect(parseReadUrlTarget("https://example.com/foo:raw")).toEqual({
|
|
path: "https://example.com/foo",
|
|
raw: true,
|
|
});
|
|
});
|
|
|
|
it("peels a single line range as offset/limit", () => {
|
|
expect(parseReadUrlTarget("https://example.com/foo:50-100")).toEqual({
|
|
path: "https://example.com/foo",
|
|
raw: false,
|
|
offset: 50,
|
|
limit: 51,
|
|
});
|
|
expect(parseReadUrlTarget("https://example.com/foo:50+10")).toEqual({
|
|
path: "https://example.com/foo",
|
|
raw: false,
|
|
offset: 50,
|
|
limit: 10,
|
|
});
|
|
expect(parseReadUrlTarget("https://example.com/foo:50")).toEqual({
|
|
path: "https://example.com/foo",
|
|
raw: false,
|
|
offset: 50,
|
|
});
|
|
});
|
|
|
|
it("peels multi-range selectors into ranges (regression: was stuck on URL → 404)", () => {
|
|
// Direct repro of bug report 6234.
|
|
const result = parseReadUrlTarget("https://raw.githubusercontent.com/oven-sh/bun/main/README.md:5-10,20-30");
|
|
expect(result).toEqual({
|
|
path: "https://raw.githubusercontent.com/oven-sh/bun/main/README.md",
|
|
raw: false,
|
|
ranges: [
|
|
{ startLine: 5, endLine: 10 },
|
|
{ startLine: 20, endLine: 30 },
|
|
],
|
|
});
|
|
});
|
|
|
|
it("peels raw + range combos in both orders (regression: was stuck on URL → 404)", () => {
|
|
// Direct repro of bug report 6230.
|
|
expect(parseReadUrlTarget("https://example.com/foo:raw:1-120")).toEqual({
|
|
path: "https://example.com/foo",
|
|
raw: true,
|
|
offset: 1,
|
|
limit: 120,
|
|
});
|
|
expect(parseReadUrlTarget("https://example.com/foo:1-120:raw")).toEqual({
|
|
path: "https://example.com/foo",
|
|
raw: true,
|
|
offset: 1,
|
|
limit: 120,
|
|
});
|
|
});
|
|
|
|
it("rejects two range groups on the same URL", () => {
|
|
expect(() => parseReadUrlTarget("https://example.com/foo:5-10:20-30")).toThrow(/range groups/);
|
|
});
|
|
|
|
it("leaves URL ports intact", () => {
|
|
// `:8080` after the host has no trailing selector character — port stays put.
|
|
expect(parseReadUrlTarget("https://example.com:8080/foo")).toEqual({
|
|
path: "https://example.com:8080/foo",
|
|
raw: false,
|
|
});
|
|
// Port + selector combo still works because the selector sits on a path segment.
|
|
expect(parseReadUrlTarget("https://example.com:8080/foo:raw")).toEqual({
|
|
path: "https://example.com:8080/foo",
|
|
raw: true,
|
|
});
|
|
});
|
|
|
|
it("treats trailing-colon selectors that don't parse as part of the URL", () => {
|
|
// `:abc` is not a selector token; the parser leaves it on the URL.
|
|
expect(parseReadUrlTarget("https://example.com/foo:abc")).toEqual({
|
|
path: "https://example.com/foo:abc",
|
|
raw: false,
|
|
});
|
|
});
|
|
|
|
it("supports the documented `host:port/` escape for naked-host selectors", () => {
|
|
// `https://example.com/:80` is the documented form to read line 80 of the homepage.
|
|
expect(parseReadUrlTarget("https://example.com/:80")).toEqual({
|
|
path: "https://example.com/",
|
|
raw: false,
|
|
offset: 80,
|
|
});
|
|
});
|
|
});
|