Line numbers are places in import and export; fix stale scripts
Import: each row's place is its line number, so blank lines leave a
place empty; a fully numbered text file ("38. Title") or a Rank column
gives places directly, and repeated numbers take the next free place.
Entries are added at those places (existing ones there move down), the
review shows each row's #, and the room check covers the highest place.
Export writes a blank line for every empty place, so line N is #N and a
file round-trips.
Static files now carry an ETag and unversioned ones are revalidated on
every load. Scripts import each other without a ?v= tag, so browsers kept
an hour-old import.js (with the "null" bug) after an update.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
88373176f2
commit
62fcf6b45d
7 files changed
+151
-72
No files matched your search
@@ -1,6 +1,7 @@
|
||||
package importer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
@@ -8,17 +9,28 @@ import (
|
||||
)
|
||||
|
||||
func TestParseText(t *testing.T) {
|
||||
got, err := Parse([]byte("1. Heat (1995)\n2) 2001: A Space Odyssey\n\n3 - Alien [1979]\n"), "list.txt")
|
||||
got, err := Parse([]byte("1. Heat (1995)\n2) 2001: A Space Odyssey\n\n4 - Alien [1979]\n"), "list.txt")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := []Row{{Title: "Heat", Year: "1995"}, {Title: "2001: A Space Odyssey"}, {Title: "Alien", Year: "1979"}}
|
||||
want := []Row{{Place: 1, Title: "Heat", Year: "1995"}, {Place: 2, Title: "2001: A Space Odyssey"}, {Place: 4, Title: "Alien", Year: "1979"}}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("got %+v", got)
|
||||
}
|
||||
// Not every line is numbered, so nothing is stripped.
|
||||
got, _ = Parse([]byte("2001: A Space Odyssey\nHeat\n1917\n"), "x.txt")
|
||||
if got[0].Title != "2001: A Space Odyssey" || got[2].Title != "1917" {
|
||||
// Not every line is numbered, so nothing is stripped; line numbers are
|
||||
// the places, and a blank line leaves one empty.
|
||||
got, _ = Parse([]byte("2001: A Space Odyssey\nHeat\n\n1917\n"), "x.txt")
|
||||
if got[0].Title != "2001: A Space Odyssey" || got[2].Title != "1917" || got[2].Place != 4 {
|
||||
t.Fatalf("got %+v", got)
|
||||
}
|
||||
// Numbers win over line numbers when every line has one.
|
||||
got, _ = Parse([]byte("1. Super Mario Sunshine\n38. Super Mario World\n"), "games.txt")
|
||||
if got[0].Place != 1 || got[1].Place != 38 || got[1].Title != "Super Mario World" {
|
||||
t.Fatalf("got %+v", got)
|
||||
}
|
||||
// A repeated number takes the next free place, keeping the file's order.
|
||||
got, _ = Parse([]byte("3. A\n3. B\n1. C\n"), "x.txt")
|
||||
if fmt.Sprint(got) != fmt.Sprint([]Row{{Place: 1, Title: "C"}, {Place: 3, Title: "A"}, {Place: 4, Title: "B"}}) {
|
||||
t.Fatalf("got %+v", got)
|
||||
}
|
||||
}
|
||||
@@ -30,20 +42,26 @@ func TestParseCSV(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := []Row{
|
||||
{Title: "Heat", Year: "1995", Subtitle: "Michael Mann"},
|
||||
{Title: "Alien", Year: "1979", Subtitle: "Ridley Scott", Note: "Tense, perfect"},
|
||||
{Place: 1, Title: "Heat", Year: "1995", Subtitle: "Michael Mann"},
|
||||
{Place: 2, Title: "Alien", Year: "1979", Subtitle: "Ridley Scott", Note: "Tense, perfect"},
|
||||
}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("got %+v", got)
|
||||
}
|
||||
// Canon's own export: one quoted column, no header.
|
||||
got, _ = Parse([]byte("\xef\xbb\xbf\"Heat\"\r\n\"Crouching Tiger, Hidden Dragon\"\r\n"), "films.csv")
|
||||
if len(got) != 2 || got[1].Title != "Crouching Tiger, Hidden Dragon" {
|
||||
// Canon's own export: one column, no header, a blank line for an empty
|
||||
// place.
|
||||
got, _ = Parse([]byte("\xef\xbb\xbfHeat\r\n\r\n\"Crouching Tiger, Hidden Dragon\"\r\n"), "films.csv")
|
||||
if len(got) != 2 || got[1].Title != "Crouching Tiger, Hidden Dragon" || got[1].Place != 3 {
|
||||
t.Fatalf("got %+v", got)
|
||||
}
|
||||
// With a header, the first row after it is #1.
|
||||
got, _ = Parse([]byte("Title\nHeat\n\nAlien\n"), "x.csv")
|
||||
if got[0].Place != 1 || got[1].Place != 3 {
|
||||
t.Fatalf("got %+v", got)
|
||||
}
|
||||
// Headerless rank,title,year.
|
||||
got, _ = Parse([]byte("1,Heat,1995\n2,Alien,1979\n"), "x.csv")
|
||||
if got[1] != (Row{Title: "Alien", Year: "1979"}) {
|
||||
got, _ = Parse([]byte("1,Heat,1995\n5,Alien,1979\n"), "x.csv")
|
||||
if got[1] != (Row{Place: 5, Title: "Alien", Year: "1979"}) {
|
||||
t.Fatalf("got %+v", got)
|
||||
}
|
||||
if _, err := Parse([]byte("\n \n"), "x.txt"); err != ErrEmpty {
|
||||
|
||||
Reference in new issue
Block a user