carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package main
2
3// The CLI-side gates for `carlos features` (issue #347): argument parsing
4// and the refusals that fail before any network call.
5
6import (
7 "os/exec"
8 "reflect"
9 "strings"
10 "testing"
11)
12
13func TestParseFeatureArgs(t *testing.T) {
14 set, unset, err := parseFeatureArgs([]string{"sandbox=on", "beta=", "limit=10 per day"})
15 if err != nil {
16 t.Fatal(err)
17 }
18 if want := map[string]string{"sandbox": "on", "limit": "10 per day"}; !reflect.DeepEqual(set, want) {
19 t.Fatalf("set = %v, want %v", set, want)
20 }
21 if want := []string{"beta"}; !reflect.DeepEqual(unset, want) {
22 t.Fatalf("unset = %v, want %v", unset, want)
23 }
24}
25
26func TestParseFeatureArgsRefusals(t *testing.T) {
27 for _, c := range []struct {
28 args []string
29 want string
30 }{
31 {[]string{"sandbox"}, "key=value"},
32 {[]string{"=on"}, "key"},
33 {[]string{"Sandbox=on"}, "key"},
34 {[]string{"sandbox=on", "sandbox=off"}, "twice"},
35 {[]string{"sandbox=on", "sandbox="}, "twice"},
36 } {
37 _, _, err := parseFeatureArgs(c.args)
38 if err == nil || !strings.Contains(err.Error(), c.want) {
39 t.Errorf("%v: err = %v, want one mentioning %q", c.args, err, c.want)
40 }
41 }
42}
43
44func runFeaturesCLI(t *testing.T, args ...string) (string, error) {
45 t.Helper()
46 bin := buildCarlos(t)
47 cmd := exec.Command(bin, args...)
48 cmd.Env = carlosTestEnv(t)
49 cmd.Dir = t.TempDir()
50 out, err := cmd.CombinedOutput()
51 return string(out), err
52}
53
54func TestFeaturesNeedsASubVerb(t *testing.T) {
55 out, err := runFeaturesCLI(t, "features")
56 if err == nil {
57 t.Fatalf("bare `features` exited 0: %s", out)
58 }
59 if !strings.Contains(out, "set") || !strings.Contains(out, "list") {
60 t.Fatalf("usage should name the sub-verbs, got: %s", out)
61 }
62}
63
64func TestFeaturesSetRefusesNoPairsBeforeTheNetwork(t *testing.T) {
65 // No pairs is a usage error, refused before the session is resolved —
66 // so it must NOT be the no-target refusal.
67 out, err := runFeaturesCLI(t, "features", "set", "-app", "titogo")
68 if err == nil {
69 t.Fatalf("set with no pairs exited 0: %s", out)
70 }
71 if !strings.Contains(out, "key=value") || strings.Contains(out, "no deployment target") {
72 t.Fatalf("want a key=value usage refusal, got: %s", out)
73 }
74}
75
76func TestFeaturesListNeedsASession(t *testing.T) {
77 out, err := runFeaturesCLI(t, "features", "list", "-app", "titogo")
78 if err == nil {
79 t.Fatalf("list with no target exited 0: %s", out)
80 }
81 if !strings.Contains(out, "no deployment target configured") {
82 t.Fatalf("want the no-target refusal, got: %s", out)
83 }
84}
85