cat / 012
clone

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

main
012 / internal / nushell / ide_test.go
ide_test.go 4.2K
1package nushell23import (4 "context"5 "errors"6 "os"7 "os/exec"8 "path/filepath"9 "slices"10 "strings"11 "testing"12)1314// testdata/ide holds nu 0.116's answers about the scripts beside them15// (ast.nu, check.nu, complete.nu at its end): what 012 relies on nu16// saying.17func recorded(t *testing.T, name string) []byte {18 t.Helper()19 data, err := os.ReadFile(filepath.Join("testdata", "ide", name))20 if err != nil {21 t.Fatal(err)22 }23 return data24}2526func TestParseAST(t *testing.T) {27 shapes, err := ParseAST(recorded(t, "ast.json"))28 if err != nil {29 t.Fatal(err)30 }31 src := string(recorded(t, "ast.nu"))32 var got []string33 for _, s := range shapes {34 got = append(got, src[s.From:s.To]+"="+strings.TrimPrefix(s.Shape, "shape_"))35 }36 want := []string{"ls=internalcall", "|=pipe", "where=internalcall", "size=string", "size=variable", ">=operator",37 "1=int", "kb=string", "|=pipe", "sort-by=internalcall", "name=string", "--reverse=flag"}38 if !slices.Equal(got, want) {39 t.Errorf("shapes\n got %q\nwant %q", got, want)40 }41 if _, err := ParseAST([]byte("Error: unknown flag")); !errors.Is(err, ErrOld) {42 t.Errorf("unreadable answer: %v", err)43 }44}4546func TestParseCheck(t *testing.T) {47 probs, err := ParseCheck(recorded(t, "check.jsonl"))48 if err != nil {49 t.Fatal(err)50 }51 src := string(recorded(t, "check.nu"))52 var got []string53 for _, p := range probs {54 got = append(got, src[p.From:p.To]+": "+p.Msg)55 }56 want := []string{"(: Unclosed delimiter.", "--foo: The `math sum` command doesn't have flag `foo`.", ": Unclosed delimiter.",57 "(: Type mismatch.", "where: Command does not support number input."}58 if !slices.Equal(got, want) {59 t.Errorf("problems\n got %q\nwant %q", got, want)60 }61 probs, err = ParseCheck([]byte(`{"type":"hint","typename":"any","position":{"start":4,"end":6}}` + "\n"))62 if err != nil || len(probs) != 0 {63 t.Errorf("hints are left out: %v %v", probs, err)64 }65}6667func TestParseComplete(t *testing.T) {68 got, err := ParseComplete(recorded(t, "complete.json"))69 if err != nil || !slices.Equal(got, []string{"sort", "sort-by", "source", "source-env"}) {70 t.Errorf("completions %q %v", got, err)71 }72 if got, err := ParseComplete([]byte(`{"completions": []}`)); err != nil || len(got) != 0 {73 t.Errorf("none %q %v", got, err)74 }75 if _, err := ParseComplete([]byte(`{"other": 1}`)); !errors.Is(err, ErrOld) {76 t.Errorf("unreadable answer: %v", err)77 }78}7980func TestVersion(t *testing.T) {81 f := &fake{out: string(recorded(t, "version.txt"))}82 if v, err := Version(context.Background(), f); err != nil || v != "0.116.0" || !slices.Equal(f.job.IDE, []string{"--version"}) {83 t.Errorf("version %q %v %q", v, err, f.job.IDE)84 }85 if _, err := Version(context.Background(), &fake{out: "0.99.1\n"}); !errors.Is(err, ErrOld) {86 t.Errorf("an old nu: %v", err)87 }88 for v, want := range map[string]bool{"0.100.0": true, "0.117.0-nightly.3": true, "1.0.0": true, "0.99.9": false, "nu": false} {89 if AtLeast(v, MinVersion) != want {90 t.Errorf("AtLeast(%q) = %v", v, !want)91 }92 }93}9495// The script asked about reaches the runner as it is, with the flags.96func TestAskHandsTheScript(t *testing.T) {97 f := &fake{out: `{"completions": ["sort"]}`}98 if _, err := Complete(context.Background(), f, "ls | so", 7); err != nil {99 t.Fatal(err)100 }101 if f.script != "ls | so" || !slices.Equal(f.job.IDE, []string{"--ide-complete", "7"}) {102 t.Errorf("script %q flags %q", f.script, f.job.IDE)103 }104}105106// The real nu, when it's installed, says what the recorded answers do.107func TestNuIDE(t *testing.T) {108 if _, err := exec.LookPath("nu"); err != nil {109 t.Skip("nu isn't installed")110 }111 ctx := context.Background()112 if _, err := Version(ctx, Nu{}); err != nil {113 t.Skipf("nu: %v", err)114 }115 shapes, err := AST(ctx, Nu{}, string(recorded(t, "ast.nu")))116 if err != nil || len(shapes) < 5 || shapes[0] != (Shape{0, 2, "shape_internalcall"}) {117 t.Errorf("ast %v %v", shapes, err)118 }119 probs, err := Check(ctx, Nu{}, string(recorded(t, "check.nu")), 20)120 if err != nil || !slices.ContainsFunc(probs, func(p Problem) bool { return strings.Contains(p.Msg, "flag `foo`") }) {121 t.Errorf("check %v %v", probs, err)122 }123 comp, err := Complete(ctx, Nu{}, "ls | so", 7)124 if err != nil || !slices.Contains(comp, "sort-by") {125 t.Errorf("complete %q %v", comp, err)126 }127}