repos
/ orchard main

orchard

mirror

Every site I host, in one repo, along with the Cloudflare Tunnel and Caddy that front them. It's all Go, Vite, and SQLite, and it runs on a desktop at home with nothing listening on an inbound port.

blogbuncaddycloudflare-tunneldockergogolanghomelabhtml-templatemonorepoself-hostedseosqlitestatic-sitetypstuptime-monitoringviteweb-analytics

4.9 KB · 169 lines · Go Raw History
  1package main
  2
  3import (
  4	"context"
  5	"io"
  6	"net/http"
  7	"strings"
  8	"testing"
  9)
 10
 11func TestPythonDepsSkipsStdlibAndMapsNames(t *testing.T) {
 12	code := strings.Join([]string{
 13		"import os, json",
 14		"import requests",
 15		"from flask import Flask, jsonify",
 16		"import yfinance as yf",
 17		"from bs4 import BeautifulSoup",
 18		"import yaml",
 19	}, "\n")
 20	got := names(pythonDeps(code))
 21	want := []string{"requests", "flask", "yfinance", "beautifulsoup4", "pyyaml"}
 22	if !sameSet(got, want) {
 23		t.Errorf("got %v, want %v", got, want)
 24	}
 25}
 26
 27func TestJSDepsSkipsRelativeAndBuiltin(t *testing.T) {
 28	code := strings.Join([]string{
 29		`import express from "express";`,
 30		`import { z } from "@hono/zod-validator";`,
 31		`const fs = require("node:fs");`,
 32		`import local from "./util.js";`,
 33	}, "\n")
 34	got := names(jsDeps(code))
 35	if !sameSet(got, []string{"express", "@hono/zod-validator"}) {
 36		t.Errorf("got %v", got)
 37	}
 38}
 39
 40func TestGoDepsTrimsToTheModuleRoot(t *testing.T) {
 41	code := "import (\n\t\"fmt\"\n\t\"github.com/gin-gonic/gin/binding\"\n\t\"modernc.org/sqlite\"\n)\n"
 42	got := names(goDeps(code))
 43	if !sameSet(got, []string{"github.com/gin-gonic/gin", "modernc.org/sqlite"}) {
 44		t.Errorf("got %v", got)
 45	}
 46}
 47
 48func TestDockerRepoNormalises(t *testing.T) {
 49	cases := map[string]string{
 50		"ollama/ollama:latest":     "ollama/ollama",
 51		"python:3.12-slim":         "library/python",
 52		"alpine":                   "library/alpine",
 53		"builder":                  "",
 54		"scratch":                  "",
 55		"ghcr.io/someone/thing:v1": "",
 56		"$BASE_IMAGE":              "",
 57	}
 58	for in, want := range cases {
 59		if got := dockerRepo(in); got != want {
 60			t.Errorf("dockerRepo(%q) = %q, want %q", in, got, want)
 61		}
 62	}
 63}
 64
 65func TestShellDepsReadsInstallLines(t *testing.T) {
 66	code := "pip install flask==3.0.0 requests\nnpm install -g typescript\ndocker run -d --name ollama -p 11434:11434 ollama/ollama\n"
 67	deps := shellDeps(code)
 68	got := names(deps)
 69	if !sameSet(got, []string{"flask", "requests", "typescript", "ollama/ollama"}) {
 70		t.Errorf("got %v", got)
 71	}
 72}
 73
 74func TestGoProxyEscape(t *testing.T) {
 75	if got := goProxyEscape("github.com/BurntSushi/toml"); got != "github.com/!burnt!sushi/toml" {
 76		t.Errorf("got %q", got)
 77	}
 78}
 79
 80// stubRegistry answers as the four registries would, so the lookup path is
 81// exercised without touching the network.
 82type stubRegistry struct{ known map[string]bool }
 83
 84func (s stubRegistry) RoundTrip(r *http.Request) (*http.Response, error) {
 85	code := http.StatusNotFound
 86	if s.known[r.URL.Host+r.URL.Path] {
 87		code = http.StatusOK
 88	}
 89	return &http.Response{
 90		StatusCode: code,
 91		Body:       io.NopCloser(strings.NewReader("{}")),
 92		Header:     make(http.Header),
 93		Request:    r,
 94	}, nil
 95}
 96
 97func TestVerifyDepsMarksTheMissingOne(t *testing.T) {
 98	client := &http.Client{Transport: stubRegistry{known: map[string]bool{
 99		"pypi.org/pypi/flask/json": true,
100	}}}
101	blocks := []CodeBlock{{Lang: "python", Closed: true, Code: "import flask\nimport flask_yahoo_cache\n"}}
102
103	deps := verifyDeps(context.Background(), client, blocks)
104	if len(deps) != 2 {
105		t.Fatalf("want 2 deps, got %+v", deps)
106	}
107	byName := map[string]Dependency{}
108	for _, d := range deps {
109		byName[d.Name] = d
110	}
111	if !byName["flask"].Found || !byName["flask"].Checked {
112		t.Errorf("flask should be found: %+v", byName["flask"])
113	}
114	if byName["flask-yahoo-cache"].Found {
115		t.Errorf("an invented package was reported as real: %+v", byName["flask-yahoo-cache"])
116	}
117	warns := depWarnings(deps)
118	if len(warns) != 1 || !strings.Contains(warns[0], "flask-yahoo-cache") {
119		t.Errorf("want one warning naming the missing package, got %v", warns)
120	}
121}
122
123// A registry that will not answer is not evidence of anything, and saying a
124// real package does not exist is worse than saying nothing.
125func TestVerifyDepsStaysQuietWhenTheRegistryIsDown(t *testing.T) {
126	client := &http.Client{Transport: roundTripFunc(func(*http.Request) (*http.Response, error) {
127		return &http.Response{StatusCode: http.StatusTooManyRequests, Body: io.NopCloser(strings.NewReader("")), Header: make(http.Header)}, nil
128	})}
129	deps := verifyDeps(context.Background(), client, []CodeBlock{{Lang: "python", Closed: true, Code: "import requests\n"}})
130	if len(deps) != 1 || deps[0].Checked {
131		t.Fatalf("a throttled registry should leave the dep unchecked: %+v", deps)
132	}
133	if warns := depWarnings(deps); len(warns) != 0 {
134		t.Errorf("nothing should be warned about, got %v", warns)
135	}
136}
137
138type roundTripFunc func(*http.Request) (*http.Response, error)
139
140func (f roundTripFunc) RoundTrip(r *http.Request) (*http.Response, error) { return f(r) }
141
142func names(deps []Dependency) []string {
143	out := make([]string, 0, len(deps))
144	seen := map[string]bool{}
145	for _, d := range deps {
146		if !seen[d.Name] {
147			seen[d.Name] = true
148			out = append(out, d.Name)
149		}
150	}
151	return out
152}
153
154func sameSet(got, want []string) bool {
155	if len(got) != len(want) {
156		return false
157	}
158	have := map[string]bool{}
159	for _, g := range got {
160		have[g] = true
161	}
162	for _, w := range want {
163		if !have[w] {
164			return false
165		}
166	}
167	return true
168}