1package nushell23import (4 "context"5 "errors"6 "os/exec"7 "slices"8 "strings"9 "testing"10)1112// hoverAsked are the bytes of testdata/ide/hover.nu that hover-*.json13// record nu's hover at.14var hoverAsked = map[string]int{"sort-by": 17, "flag": 30, "into-string": 45, "variable": 76, "none": 15}1516func TestParseHover(t *testing.T) {17 src := string(recorded(t, "hover.nu"))18 for name, want := range map[string]string{"sort-by": "sort-by", "flag": "--reverse", "into-string": "into string", "variable": "$n"} {19 h, ok, err := ParseHover(recorded(t, "hover-"+name+".json"))20 if err != nil || !ok || src[h.From:h.To] != want {21 t.Errorf("%s: %+v %v %v", name, h, ok, err)22 }23 }24 if h, ok, err := ParseHover(recorded(t, "hover-variable.json")); !ok || err != nil || h.Text != "int" {25 t.Errorf("a variable's type: %q", h.Text)26 }27 if _, ok, err := ParseHover(recorded(t, "hover-none.json")); ok || err != nil {28 t.Errorf("no word: %v %v", ok, err)29 }30 if _, _, err := ParseHover([]byte(`{"other": 1}`)); !errors.Is(err, ErrOld) {31 t.Errorf("unreadable answer: %v", err)32 }33}3435func TestParseHelp(t *testing.T) {36 h, _, _ := ParseHover(recorded(t, "hover-sort-by.json"))37 help, ok := ParseHelp(h.Text)38 if !ok || help.Name != "sort-by" || help.Summary() != "Sort by the given cell path or closure." {39 t.Fatalf("help %+v", help)40 }41 if got := help.Signature(); got != "sort-by <...comparator: cell-path|closure> --reverse --ignore-case --natural --custom" {42 t.Errorf("signature %q", got)43 }44 if got := help.Brief(); got != "sort-by <...comparator> …" {45 t.Errorf("brief %q", got)46 }47 if f, ok := help.Flag("-r"); !ok || f.Long != "--reverse" || f.Desc != "Sort in reverse order." {48 t.Errorf("-r: %+v", f)49 }50 if _, ok := help.Flag("--help"); ok {51 t.Error("--help is every command's")52 }53 if !slices.Equal(help.Types, []string{"list<any> | list<any>", "record | table", "table | table"}) {54 t.Errorf("types %q", help.Types)55 }56 if len(help.Examples) != 6 || help.Examples[0] != (Example{"Sort files by modified date.", "ls | sort-by modified"}) {57 t.Errorf("examples %q", help.Examples)58 }59 h, _, _ = ParseHover(recorded(t, "hover-into-string.json"))60 help, _ = ParseHelp(h.Text)61 if got := help.Signature(); got != "into string <...rest: cell-path> --group-digits --decimals <int>" {62 t.Errorf("signature %q", got)63 }64 if help.Name != "into string" || DocsURL(help.Name) != "https://www.nushell.sh/commands/docs/into_string.html" {65 t.Errorf("docs of %q: %s", help.Name, DocsURL(help.Name))66 }67 if _, ok := ParseHelp("int"); ok {68 t.Error("a variable's type read as help")69 }70}7172// A command of the script's own, without a description.73func TestParseHelpOfADef(t *testing.T) {74 help, ok := ParseHelp("\n### Usage\n```\n greet {flags} <name>\n```\n\n### Flags\n\n `--loud`\\\n `-h`, `--help` - Display the help message for this command\n\n### Parameters\n\n `name: string`\n\n")75 if !ok || help.Desc != "" || help.Signature() != "greet <name: string> --loud" {76 t.Errorf("help %+v %q", help, help.Signature())77 }78}7980// The real nu, when it's the version recorded, says what hover-*.json81// record.82func TestNuHover(t *testing.T) {83 if _, err := exec.LookPath("nu"); err != nil {84 t.Skip("nu isn't installed")85 }86 if v, err := Version(context.Background(), Nu{}); err != nil || v != strings.TrimSpace(string(recorded(t, "version.txt"))) {87 t.Skipf("nu %s %v isn't the version recorded", v, err)88 }89 src := string(recorded(t, "hover.nu"))90 for name, at := range hoverAsked {91 got, gotOK, err := HoverAt(context.Background(), Nu{}, src, at)92 want, wantOK, _ := ParseHover(recorded(t, "hover-"+name+".json"))93 if err != nil || got != want || gotOK != wantOK {94 t.Errorf("%s: nu says %+v %v %v, recorded %+v", name, got, gotOK, err, want)95 }96 }97}