initial public release
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
package eval
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
func TestBatch_EmptyInputClosesChannel(t *testing.T) {
|
||||
b := &Batch{Concurrency: 3}
|
||||
ch := b.Run(context.Background(), nil)
|
||||
select {
|
||||
case _, ok := <-ch:
|
||||
if ok {
|
||||
t.Fatal("expected closed channel for empty input")
|
||||
}
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
t.Fatal("channel did not close")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBatch_NilClientErrorsEveryJob(t *testing.T) {
|
||||
b := &Batch{Concurrency: 2}
|
||||
jobs := []JobContext{
|
||||
{URL: "https://a", Company: "A", Title: "T"},
|
||||
{URL: "https://b", Company: "B", Title: "T"},
|
||||
}
|
||||
ch := b.Run(context.Background(), jobs)
|
||||
var starts, errors int
|
||||
for ev := range ch {
|
||||
switch ev.Kind {
|
||||
case EventStart:
|
||||
starts++
|
||||
case EventError:
|
||||
errors++
|
||||
case EventDone:
|
||||
t.Fatalf("unexpected EventDone with nil client")
|
||||
}
|
||||
}
|
||||
if starts != 2 || errors != 2 {
|
||||
t.Errorf("starts=%d errors=%d, want 2/2", starts, errors)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBatch_DemoteBelowMinScore(t *testing.T) {
|
||||
db := setupReportDB(t)
|
||||
defer db.Close()
|
||||
// Seed a job + application row (Evaluated, score=3.0).
|
||||
if _, err := db.Exec(`INSERT INTO jobs (url, company, title, source) VALUES (?, ?, ?, ?)`,
|
||||
"https://x/1", "Acme", "Engineer", "test"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var jobID int64
|
||||
if err := db.QueryRow(`SELECT id FROM jobs WHERE url = ?`, "https://x/1").Scan(&jobID); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
res, err := db.Exec(`INSERT INTO applications (job_id, status, score) VALUES (?, 'Evaluated', 3.0)`, jobID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
appID, _ := res.LastInsertId()
|
||||
|
||||
b := &Batch{DB: db, MinScore: 4.0}
|
||||
if err := b.demoteBelowScore(context.Background(), appID); err != nil {
|
||||
t.Fatalf("demote: %v", err)
|
||||
}
|
||||
var status string
|
||||
if err := db.QueryRow(`SELECT status FROM applications WHERE id = ?`, appID).Scan(&status); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if status != "Discarded" {
|
||||
t.Errorf("status = %q, want Discarded", status)
|
||||
}
|
||||
|
||||
// Now set the row to Applied and re-run demote — it must NOT regress.
|
||||
if _, err := db.Exec(`UPDATE applications SET status = 'Applied' WHERE id = ?`, appID); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := b.demoteBelowScore(context.Background(), appID); err != nil {
|
||||
t.Fatalf("demote#2: %v", err)
|
||||
}
|
||||
_ = db.QueryRow(`SELECT status FROM applications WHERE id = ?`, appID).Scan(&status)
|
||||
if status != "Applied" {
|
||||
t.Errorf("user-advanced status must be preserved, got %q", status)
|
||||
}
|
||||
}
|
||||
|
||||
// silence unused-import warning when the only test using sql is compiled out.
|
||||
var _ = (*sql.DB)(nil)
|
||||
|
||||
func TestBatch_ContextCanceledBeforeStart(t *testing.T) {
|
||||
b := &Batch{Concurrency: 1}
|
||||
jobs := []JobContext{{URL: "https://x", Company: "X", Title: "T"}}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
ch := b.Run(ctx, jobs)
|
||||
var errs int
|
||||
for ev := range ch {
|
||||
if ev.Kind == EventError {
|
||||
errs++
|
||||
}
|
||||
}
|
||||
if errs != 1 {
|
||||
t.Errorf("expected 1 error from canceled batch, got %d", errs)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user