Serveur Go : recherche GitHub par critères

- /api/search traduit les filtres en requête GitHub (langage, étoiles,
  activité, création, licence, topic, forks, archivés, good first issues)
- cache mémoire des recherches identiques (CACHE_TTL) et suivi du quota
- /api/status, /healthz, authentification basique optionnelle
- Dockerfile et docker-compose.yml

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
claude BotandClaude Opus 5.5 committed 2026-10-01 12:46:42 +02:00
1 parent 04379490f1
commit 1885488d05
9 files changed
+472

No files matched your search

+52
View File
@@ -0,0 +1,52 @@
package main
import (
"net/url"
"testing"
"time"
)
func TestQuery(t *testing.T) {
now := time.Date(2026, 10, 1, 12, 0, 0, 0, time.UTC)
tests := []struct {
params string
want string
}{
{"", "archived:false stars:>=1"},
{"q=log+viewer&in=name", "log viewer in:name archived:false"},
{"language=Go&stars=100", "language:Go stars:>=100 archived:false"},
{"stars=10&maxstars=500&minforks=5", "stars:10..500 forks:>=5 archived:false"},
{"topic=CLI&license=MIT&archived=1&forks=1", "topic:cli license:mit fork:true"},
{"q=syslog&pushed=1y&created=1m&goodfirst=1", "syslog pushed:>=2025-10-01 created:>=2026-09-01 archived:false good-first-issues:>0"},
}
for _, tt := range tests {
v, _ := url.ParseQuery(tt.params)
c, err := ParseCriteria(v)
if err != nil {
t.Fatalf("%q: %v", tt.params, err)
}
if got := c.Query(now); got != tt.want {
t.Errorf("%q:\n got %q\n want %q", tt.params, got, tt.want)
}
}
}
func TestParseCriteriaErrors(t *testing.T) {
for _, p := range []string{
"stars=-1", "stars=abc", "pushed=3d", "sort=name", "in=code",
"language=go%20lang%3Arm", "topic=a:b", "page=40&per_page=30",
} {
v, _ := url.ParseQuery(p)
if _, err := ParseCriteria(v); err == nil {
t.Errorf("%q: expected an error", p)
}
}
}
func TestPerPageCap(t *testing.T) {
v, _ := url.ParseQuery("per_page=500")
c, err := ParseCriteria(v)
if err != nil || c.PerPage != 100 {
t.Fatalf("per_page=500: got %d, %v", c.PerPage, err)
}
}