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 / e2e / screenrules_test.go
screenrules_test.go 4.2K
1package e2e23import (4 "os"5 "path/filepath"6 "testing"7)89// tasksBook is a task list with rules on every column: owners from a10// dropdown (one of them not on its list), hours on a color scale, done11// tasks struck through in green, and checkboxes.12const tasksBook = `{13 "version": 2,14 "widths": {"A": 14, "B": 10, "C": 8, "D": 7},15 "cells": {16 "A1": {"input":"Task","bold":true},17 "B1": {"input":"Owner","bold":true},18 "C1": {"input":"Hours","bold":true,"align":"right"},19 "D1": {"input":"Done","bold":true,"align":"center"},20 "A2": "Write spec", "B2": "Ann", "C2": "12", "D2": "TRUE",21 "A3": "Build UI", "B3": "Bo", "C3": "40", "D3": "FALSE",22 "A4": "Tests", "B4": "Cy", "C4": "26", "D4": "TRUE",23 "A5": "Docs", "B5": "Dee", "C5": "6",24 "A6": "Release", "B6": "Ann", "C6": "3", "D6": "FALSE",25 "A7": "Total", "C7": "=SUM(C2:C6)"26 },27 "conditionalFormats": [28 {"ranges":"A2:A6","condition":"formula","values":["=$D2"],"text":"green","strikethrough":true},29 {"ranges":"C2:C6","scale":[{"type":"min","color":"green"},{"type":"percentile","value":"50","color":"yellow"},{"type":"max","color":"red"}]},30 {"ranges":"C7","condition":"gt","values":["80"],"fill":"magenta","bold":true}31 ],32 "validations": [33 {"ranges":"B2:B6","criteria":"list","items":["Ann","Bo","Cy"],"help":"Pick who does it"},34 {"ranges":"D2:D6","criteria":"checkbox"},35 {"ranges":"C2:C6","criteria":"number","condition":"between","values":["0","80"],"reject":true}36 ]37}38`3940func tasksFile(t *testing.T, dir string) {41 if err := os.WriteFile(filepath.Join(dir, "tasks.012"), []byte(tasksBook), 0o644); err != nil {42 t.Fatal(err)43 }44}4546// openTasks opens the task list.47func openTasks(s *session) {48 s.keys("<ctrl+o>")49 s.waitFor("Open file:")50 s.keys("tasks", "<enter>")51 s.waitFor("Write spec")52}5354var ruleScreens = []screen{55 {name: "rules-sheet", files: tasksFile, setup: func(s *session) {56 openTasks(s)57 s.keys("<down>", "<down>", "<down>", "<down>", "<right>")58 s.waitFor("Invalid: Pick who does it")59 }},60 {name: "rules-sheet-dracula", opts: options{config: "theme = Dracula\n"}, files: tasksFile, setup: func(s *session) {61 openTasks(s)62 s.keys("<down>", "<down>", "<right>", "<right>", "<right>")63 s.waitFor("check or uncheck")64 }},65 {name: "rules-sheet-latte", opts: options{light: true, config: "theme = Catppuccin Latte\n"}, files: tasksFile, setup: func(s *session) {66 openTasks(s)67 s.keys("<down>", "<down>", "<right>", "<right>", "<right>")68 s.waitFor("check or uncheck")69 }},70 {name: "rules-panel", files: tasksFile, setup: func(s *session) {71 openTasks(s)72 s.keys("<ctrl+k>", "conditional formatting", "<enter>")73 s.waitFor("Conditional format rules")74 s.keys("<down>", "<down>")75 s.waitFor("first rule that matches")76 }},77 {name: "rules-editor", files: tasksFile, setup: func(s *session) {78 openTasks(s)79 s.keys("<ctrl+k>", "conditional formatting", "<enter>")80 s.waitFor("Conditional format rules")81 s.keys("<down>", "<enter>")82 s.waitFor("Edit conditional format")83 }},84 {name: "rules-editor-narrow", opts: options{cols: 60, rows: 16}, files: tasksFile, setup: func(s *session) {85 openTasks(s)86 s.keys("<ctrl+k>", "conditional formatting", "<enter>")87 s.waitFor("Conditional format rules")88 s.keys("<down>", "<down>", "<enter>")89 s.waitFor("Minpoint")90 }},91 {name: "validation-editor", files: tasksFile, setup: func(s *session) {92 openTasks(s)93 s.keys("<ctrl+k>", "data validation", "<enter>")94 s.waitFor("Data validation rules")95 s.keys("<down>", "<enter>")96 s.waitFor("Edit data validation")97 }},98 {name: "dropdown-open", files: tasksFile, setup: func(s *session) {99 openTasks(s)100 s.keys("<down>", "<down>", "<right>", "<alt+down>")101 s.waitFor("Search the items")102 }},103 {name: "validation-reject", files: tasksFile, setup: func(s *session) {104 openTasks(s)105 s.keys("<down>", "<right>", "<right>", "120", "<enter>")106 s.waitFor("Invalid entry in C2")107 }},108}109110func init() {111 light := map[string]bool{"rules-sheet": true, "rules-panel": true, "rules-editor": true, "validation-editor": true, "dropdown-open": true}112 for _, sc := range ruleScreens {113 screens = append(screens, sc)114 if light[sc.name] {115 sc.name += "-light"116 sc.opts.light = true117 screens = append(screens, sc)118 }119 }120}