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 / sheet / lines_test.go
lines_test.go 4.9K
1package sheet23import (4 "bytes"5 "testing"6)78func col(c int) Rect { return colRect(c, c) }910// Formatting whole columns and rows keeps the format on the line: no11// cells are made, every cell of the line shows it, and the latest12// formatting wins where lines cross or a cell differs.13func TestLineFormats(t *testing.T) {14 s := New()15 s.Set(at("B2"), "5")16 s.SetFormat(at1("B2"), Preset(FmtPercent))17 s.SetFormat(col(1), Preset(FmtCurrency))18 if n := s.cells.len(); n != 1 {19 t.Errorf("%d cells stored, want only B2", n)20 }21 for _, a := range []string{"B2", "B1", "B1048576"} {22 if f := s.DisplayFormat(at(a)); f.Kind != FmtCurrency {23 t.Errorf("%s shows %v, want currency", a, f.Kind)24 }25 }26 if c := s.Cell(at("B2")); !c.Format.IsZero() {27 t.Errorf("B2 keeps its own %v under the column's format", c.Format.Kind)28 }2930 // Bold the column, then take the bold off one cell of it.31 s.SetStyle(col(0), func(st *Style) { st.Bold = true })32 s.SetStyle(at1("A5"), func(st *Style) { st.Bold = false })33 if s.CellStyle(at("A5")).Bold || !s.CellStyle(at("A6")).Bold {34 t.Errorf("A5 bold %v, A6 bold %v", s.CellStyle(at("A5")).Bold, s.CellStyle(at("A6")).Bold)35 }36 // Styling a row changes what its cells show, column formats included.37 s.SetStyle(rowRect(2, 2), func(st *Style) { st.Italic = true })38 if st := s.CellStyle(at("A3")); !st.Italic || !st.Bold {39 t.Errorf("A3 = %+v, want the column's bold and the row's italic", st)40 }41 s.SetStyle(col(0), func(st *Style) { st.Underline = true })42 if st := s.CellStyle(at("A3")); !st.Italic || !st.Underline {43 t.Errorf("A3 after underlining column A = %+v", st)44 }45 if st := s.CellStyle(at("C3")); !st.Italic || st.Underline {46 t.Errorf("C3 = %+v, want the row's italic only", st)47 }4849 // Typing into a plain text column keeps the entry as text.50 s.SetFormat(col(3), Format{Kind: FmtText})51 s.Set(at("D7"), "0012")52 if v := s.Value(at("D7")); v.Kind != Text || v.Str != "0012" {53 t.Errorf("D7 = %+v, want the text 0012", v)54 }5556 // Saved and loaded, the formats read the same.57 var buf bytes.Buffer58 if err := s.Write(&buf); err != nil {59 t.Fatal(err)60 }61 back, err := Read(&buf)62 if err != nil {63 t.Fatalf("%v\n%s", err, buf.String())64 }65 for _, a := range []string{"A3", "A5", "A6", "C3", "B9", "D7", "Z1"} {66 if got, want := back.effective(at(a)), s.effective(at(a)); got != want {67 t.Errorf("%s after loading = %+v, want %+v", a, got, want)68 }69 if got, want := back.DisplayFormat(at(a)), s.DisplayFormat(at(a)); got != want {70 t.Errorf("%s format after loading = %+v, want %+v", a, got, want)71 }72 }73}7475func at1(a string) Rect { return Rect{From: at(a), To: at(a)} }7677// Line formats undo, redo, move with inserted columns and clear.78func TestLineFormatsUndoAndInsert(t *testing.T) {79 s := New()80 s.Set(at("C4"), "7")81 s.SetFormat(col(2), Preset(FmtCurrency))82 s.Undo()83 if f := s.DisplayFormat(at("C9")); !f.IsZero() {84 t.Errorf("after undo C9 shows %v", f.Kind)85 }86 s.Redo()87 if f := s.DisplayFormat(at("C9")); f.Kind != FmtCurrency {88 t.Errorf("after redo C9 shows %v", f.Kind)89 }90 if err := s.InsertCols(0, 2); err != nil {91 t.Fatal(err)92 }93 if f := s.DisplayFormat(at("E9")); f.Kind != FmtCurrency {94 t.Errorf("after inserting two columns E9 shows %v", f.Kind)95 }96 if f := s.DisplayFormat(at("C9")); !f.IsZero() {97 t.Errorf("after inserting two columns C9 shows %v", f.Kind)98 }99 s.ClearFormatting(col(4))100 if len(s.lines.cols) != 0 || s.DisplayFormat(at("E4")).Kind == FmtCurrency {101 t.Errorf("clearing column E left %v", s.lines.cols)102 }103}104105// Formatting the whole sheet sets the sheet's own format, once, and106// changes the columns and rows that have one so they show it too.107func TestWholeSheetFormat(t *testing.T) {108 s := New()109 s.Set(at("XFD1048576"), "1")110 s.SetStyle(col(3), func(st *Style) { st.Italic = true })111 all := Rect{To: Addr{Col: MaxCols - 1, Row: MaxRows - 1}}112 s.SetStyle(all, func(st *Style) { st.Bold = true })113 if len(s.lines.cols) != 1 || s.cells.len() != 1 || !s.lines.sheet.Style.Bold {114 t.Errorf("%d column formats, %d cells, sheet %+v", len(s.lines.cols), s.cells.len(), s.lines.sheet)115 }116 if !s.CellStyle(at("XFD1048576")).Bold || !s.CellStyle(at("Q77")).Bold {117 t.Error("not bold everywhere")118 }119 if st := s.CellStyle(at("D9")); !st.Bold || !st.Italic {120 t.Errorf("D9 = %+v, want column D's italic and the sheet's bold", st)121 }122 var buf bytes.Buffer123 s.Write(&buf)124 if !bytes.Contains(buf.Bytes(), []byte(`"A:XFD": {"bold":true}`)) {125 t.Errorf("the sheet's format isn't written:\n%.300s", buf.String())126 }127 back, err := Read(&buf)128 if err != nil {129 t.Fatal(err)130 }131 if !back.CellStyle(at("Q77")).Bold || !back.CellStyle(at("D9")).Italic || len(back.lines.cols) != 1 {132 t.Error("the sheet's format didn't load")133 }134 s.Undo()135 if s.CellStyle(at("Q77")).Bold || s.CellStyle(at("D9")).Bold {136 t.Error("undo left bold")137 }138 s.Redo()139 s.ClearFormatting(all)140 if len(s.lines.cols) != 0 || !s.lines.sheet.IsZero() {141 t.Errorf("%d column formats after clearing", len(s.lines.cols))142 }143}