`sift extract <file.pdf>` stats the file (refusing over 100 MiB before the upload), streams it as the POST body with Content-Type application/pdf and the ContentLength set, and prints the /v1/extract answer exactly as `sift fetch` prints a PDF URL — same content output, same errors and exitFor codes. parseExtractOpts reuses splitAroundPositional; extractURL sends only the set options with mode=digest when a question is given. main.go gains the case and a help line; README and skill document the command. Co-Authored-By: ornith-1.5-35b-a3b <ornith-1.5-35b-a3b@llama.cpp.invalid>
47 lines
1.6 KiB
Go
47 lines
1.6 KiB
Go
package main
|
|
|
|
// P5c task 02: `sift extract <file>` uploads a PDF to /v1/extract.
|
|
|
|
import (
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestParseExtractOpts(t *testing.T) {
|
|
o, err := parseExtractOpts([]string{"thesis.pdf", "--pages", "41-60", "--grep", "attention head"})
|
|
if err != nil || o.File != "thesis.pdf" || o.Pages != "41-60" || o.Grep != "attention head" {
|
|
t.Errorf("%+v %v", o, err)
|
|
}
|
|
o, err = parseExtractOpts([]string{"--question", "what is the method?", "--json", "paper.pdf"})
|
|
if err != nil || o.File != "paper.pdf" || o.Question != "what is the method?" || !o.JSON {
|
|
t.Errorf("flags first: %+v %v", o, err)
|
|
}
|
|
if _, err := parseExtractOpts(nil); err == nil {
|
|
t.Error("no file: want an error")
|
|
}
|
|
if _, err := parseExtractOpts([]string{"a.pdf", "b.pdf"}); err == nil {
|
|
t.Error("two files: want an error")
|
|
}
|
|
if !strings.Contains(extractUsage, "sift extract <file.pdf>") {
|
|
t.Errorf("usage %q", extractUsage)
|
|
}
|
|
}
|
|
|
|
func TestExtractURL(t *testing.T) {
|
|
u, err := url.Parse(extractURL("https://sift.example:8443", extractOpts{File: "x.pdf", Pages: "2-3", Grep: "a b&c"}))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if u.Path != "/v1/extract" || u.Query().Get("pages") != "2-3" || u.Query().Get("grep") != "a b&c" {
|
|
t.Errorf("url %s", u)
|
|
}
|
|
if u.Query().Has("question") || u.Query().Has("mode") {
|
|
t.Errorf("unset options must not be sent: %s", u)
|
|
}
|
|
u, _ = url.Parse(extractURL("https://sift.example:8443", extractOpts{File: "x.pdf", Question: "why?"}))
|
|
if u.Query().Get("question") != "why?" || u.Query().Get("mode") != "digest" {
|
|
t.Errorf("question url %s (mode must be digest with a question)", u)
|
|
}
|
|
}
|