cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

cat/module-path
012 / internal / ui / importplace_test.go
importplace_test.go 5.2K
1package ui23import (4 "context"5 "path/filepath"6 "strings"7 "testing"89 "src.rest/cat/012/internal/fileio"10 "src.rest/cat/012/internal/sheet"11 "src.rest/cat/012/internal/ui/picker"12)1314// importInto runs File > Import on name and picks place in the location15// picker.16func importInto(t *testing.T, m *Model, name, place string) {17 t.Helper()18 m.runCommand("file.import")19 press(t, m, name, "<enter>")20 p, ok := m.overlay.(*picker.Picker)21 if !ok || !strings.HasPrefix(p.Title(), "Import ") {22 t.Fatalf("no location picker: %T", m.overlay)23 }24 press(t, m, place, "<enter>")25}2627func TestImportLocation(t *testing.T) {28 t.Chdir(t.TempDir())29 writeFile(t, "sales.csv", "Region,Total\nNorth,12\n")30 m := newModel()31 press(t, m, "=sales!B2*2", "<enter>")32 m.changed = false3334 // The picker offers Sheets' choices, what the current sheet is, and35 // says what each does.36 m.runCommand("file.import")37 press(t, m, "sales.csv", "<enter>")38 got := strings.Join(pickerTitles(t, m), "\n")39 want := "Insert new sheet | after Sheet1\nReplace current sheet | Sheet1\nFollow the file | live, in a new sheet\nReplace spreadsheet | open it instead"40 if got != want {41 t.Errorf("locations:\n%s\nwant\n%s", got, want)42 }43 if st := status(m); !strings.Contains(st, "Add sales.csv as a new sheet") {44 t.Errorf("status %q", st)45 }46 press(t, m, "<esc>")47 if m.overlay != nil || m.book().Len() != 1 {48 t.Fatalf("Esc imported: %d sheets", m.book().Len())49 }5051 // Insert new sheet: one undo step, the file stays this one.52 importInto(t, m, "sales.csv", "Insert new sheet")53 if sheetNames(m) != "Sheet1,sales" || m.sheet.Name() != "sales" || input(m, "A2") != "North" {54 t.Fatalf("inserted: %s on %s", sheetNames(m), m.sheet.Name())55 }56 if line(m, contextLine) != "Imported sales.csv as sales (2 rows)" || !m.changed || m.xfer.Source != "" {57 t.Errorf("context %q changed %v source %q", line(m, contextLine), m.changed, m.xfer.Source)58 }59 if v := m.book().Sheet(0).Value(addr("A1")); v.Num != 24 {60 t.Errorf("Sheet1!A1 reading the import = %v", v)61 }62 // Again: the name is taken, so the new sheet gets a number.63 importInto(t, m, "sales.csv", "Insert new sheet")64 if sheetNames(m) != "Sheet1,sales,sales 2" || m.sheet.Name() != "sales 2" {65 t.Errorf("second insert: %s", sheetNames(m))66 }67 press(t, m, "<ctrl+z>")68 if sheetNames(m) != "Sheet1,sales" || !strings.Contains(line(m, contextLine), "Undid: import sales.csv") {69 t.Errorf("undo: %s, %q", sheetNames(m), line(m, contextLine))70 }71 // New sheets go after the sheet shown, not at the end.72 press(t, m, "<ctrl+pgup>")73 importInto(t, m, "sales.csv", "Insert new sheet")74 if sheetNames(m) != "Sheet1,sales 2,sales" || m.sheet.Name() != "sales 2" {75 t.Errorf("insert after Sheet1: %s on %s", sheetNames(m), m.sheet.Name())76 }77 press(t, m, "<ctrl+z>")7879 // Replace current sheet keeps the sheet's name, place and the charts80 // that fit the new data, removes the rest, and says which.81 press(t, m, "<ctrl+pgup>")82 m.sheet.AddChart(sheet.Chart{Data: sheet.NewRect(addr("C1"), addr("C2")), Title: "Totals"})83 m.sheet.AddChart(sheet.Chart{Data: sheet.NewRect(addr("A1"), addr("B2")), Title: "Regions"})84 writeFile(t, "sales.csv", "Region,Total\nSouth,50\n")85 importInto(t, m, "sales.csv", "Replace current sheet")86 if sheetNames(m) != "Sheet1,sales" || m.sheet.Name() != "Sheet1" || input(m, "A2") != "South" || input(m, "A1") != "Region" {87 t.Fatalf("replaced: %s on %s, A2 %q", sheetNames(m), m.sheet.Name(), input(m, "A2"))88 }89 if got := line(m, contextLine); !strings.HasPrefix(got, "Imported sales.csv into Sheet1 (2 rows); removed charts: Totals (C1:C2); charts:") {90 t.Errorf("context %q", got)91 }92 if c := m.sheet.Charts(); len(c) != 1 || c[0].Title != "Regions" {93 t.Errorf("charts after replacing: %+v", c)94 }95 press(t, m, "<ctrl+z>")96 if m.sheet.Name() != "Sheet1" || input(m, "A1") != "=sales!B2*2" || len(m.sheet.Charts()) != 2 {97 t.Errorf("undo replace: on %s, A1 %q, %d charts", m.sheet.Name(), input(m, "A1"), len(m.sheet.Charts()))98 }99}100101// An XLSX workbook inserts every sheet, names made unique, and offers no102// Replace current sheet.103func TestImportLocationWorkbook(t *testing.T) {104 t.Chdir(t.TempDir())105 src := sheet.New()106 book := src.Book()107 book.RenameSheet(src, "Sheet1")108 src.Set(addr("A1"), "1")109 q3, _ := book.AddSheet("Q3", 1)110 q3.Set(addr("A1"), "=Sheet1!A1+1")111 if _, err := fileio.Export(context.Background(), filepath.Join(".", "book.xlsx"), fileio.XLSX, fileio.SnapBook(src), fileio.ExportOptions{}); err != nil {112 t.Fatal(err)113 }114 m := newModel()115 press(t, m, "x", "<enter>")116 m.runCommand("file.import")117 press(t, m, "book", "<enter>")118 if got := strings.Join(pickerTitles(t, m), "\n"); got != "Insert new sheets | after Sheet1\nFollow the file | live, in a new sheet\nReplace spreadsheet | unsaved changes" {119 t.Errorf("locations:\n%s", got)120 }121 press(t, m, "insert", "<enter>")122 if sheetNames(m) != "Sheet1,Sheet1 2,Q3" || m.sheet.Name() != "Sheet1 2" {123 t.Fatalf("sheets %s on %s (%q)", sheetNames(m), m.sheet.Name(), m.errMsg)124 }125 if got := m.book().Lookup("Q3"); got.Cell(addr("A1")).Input != "='Sheet1 2'!A1+1" || got.Value(addr("A1")).Num != 2 {126 t.Errorf("Q3!A1 %q = %v", got.Cell(addr("A1")).Input, got.Value(addr("A1")))127 }128 if l := line(m, contextLine); l != "Imported book.xlsx as Sheet1 2 and Q3 (2 rows)" {129 t.Errorf("context %q", l)130 }131}