File: cmd_spec.rb

package info (click to toggle)
ruby-tty-command 0.10.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 452 kB
  • sloc: ruby: 1,990; makefile: 4; sh: 4
file content (176 lines) | stat: -rw-r--r-- 6,160 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# frozen_string_literal: true

RSpec.describe TTY::Command::Cmd, "::new" do
  it "requires at least command argument" do
    expect {
      TTY::Command::Cmd.new({})
    }.to raise_error(ArgumentError, /Cmd requires command argument/)
  end

  it "requires non empty command argument" do
    expect {
      TTY::Command::Cmd.new(nil)
    }.to raise_error(ArgumentError, /No command provided/)
  end

  it "accepts a command" do
    cmd = TTY::Command::Cmd.new(:echo)
    expect(cmd.command).to eq("echo")
    expect(cmd.argv).to eq([])
    expect(cmd.options).to eq({})
    expect(cmd.to_command).to eq("echo")
  end

  it "accepts a command as heredoc" do
    cmd = TTY::Command::Cmd.new <<-EOHEREDOC
      if [[ $? -eq 0]]; then
        echo "Bash it!"
      fi
    EOHEREDOC
    expect(cmd.argv).to eq([])
    expect(cmd.options).to eq({})
    expect(cmd.to_command).to eq([
      "      if [[ $? -eq 0]]; then",
      "        echo \"Bash it!\"",
      "      fi\n"
    ].join("\n"))
  end

  it "accepts command as [cmdname, arg1, ...]" do
    cmd = TTY::Command::Cmd.new(:echo, "-n", "hello")
    expect(cmd.command).to eq("echo")
    expect(cmd.argv).to eq(["-n", "hello"])
    expect(cmd.to_command).to eq("echo -n hello")
  end

  it "accepts command as [[cmdname, argv0], arg1, ...]" do
    cmd = TTY::Command::Cmd.new([:echo, "-n"], "hello")
    expect(cmd.command).to eq("echo")
    expect(cmd.argv).to eq(["-n", "hello"])
    expect(cmd.to_command).to eq("echo -n hello")
  end

  it "accepts command with environment as [cmdname, arg1, ..., opts]" do
    cmd = TTY::Command::Cmd.new(:echo, "hello", env: { foo: "bar" })
    expect(cmd.to_command).to eq(%{( export FOO=\"bar\" ; echo hello )})
  end

  it "accepts command with multiple environment keys" do
    cmd = TTY::Command::Cmd.new(:echo, "hello", env: { foo: "a", bar: "b" })
    expect(cmd.to_command).to eq(%{( export FOO=\"a\" BAR=\"b\" ; echo hello )})
  end

  it "accepts command with environemnt string keys" do
    cmd = TTY::Command::Cmd.new(:echo, "hello", env: { "FOO_bar" => "a", bar: "b" })
    expect(cmd.to_command).to eq(%{( export FOO_bar=\"a\" BAR=\"b\" ; echo hello )})
  end

  it "escapes environment values" do
    cmd = TTY::Command::Cmd.new(:echo, "hello", env: { foo: 'abc"def' })
    expect(cmd.to_command).to eq(%{( export FOO=\"abc\\\"def\" ; echo hello )})
  end

  it "accepts environment as first argument" do
    cmd = TTY::Command::Cmd.new({ "FOO" => true, "BAR" => 1 }, :echo, "hello")
    expect(cmd.to_command).to eq(%{( export FOO=\"true\" BAR=\"1\" ; echo hello )})
  end

  it "handles environment with fanky characters" do
    cmd = TTY::Command::Cmd.new(:echo, "hello", env: { foo: "%16" })
    expect(cmd.to_command).to eq(%{( export FOO=\"%16\" ; echo hello )})
  end

  it "runs command in specified directory" do
    cmd = TTY::Command::Cmd.new(:echo, "hello", chdir: "/tmp")
    expect(cmd.to_command).to eq("cd /tmp && echo hello")
  end

  it "escapes directory path with fanky characters" do
    cmd = TTY::Command::Cmd.new(:echo, "hello", chdir: "/pa%th/to dir")
    expect(cmd.to_command).to eq("cd /pa\\%th/to\\ dir && echo hello")
  end

  it "runs command in specified directory with environment" do
    cmd = TTY::Command::Cmd.new(:echo, "hello", chdir: "/tmp", env: { foo: "bar" })
    expect(cmd.to_command).to eq(%{cd /tmp && ( export FOO=\"bar\" ; echo hello )})
  end

  it "runs command as a user" do
    cmd = TTY::Command::Cmd.new(:echo, "hello", user: "piotrmurach")
    expect(cmd.to_command).to eq("sudo -u piotrmurach -- sh -c 'echo hello'")
  end

  it "runs command as a group" do
    cmd = TTY::Command::Cmd.new(:echo, "hello", group: "devs")
    expect(cmd.to_command).to eq("sg devs -c \\\"echo hello\\\"")
  end

  it "runs command as a user in a group" do
    cmd = TTY::Command::Cmd.new(:echo, "hello", user: "piotrmurach", group: "devs")
    expect(cmd.to_command).to eq("sudo -u piotrmurach -- sh -c 'sg devs -c \\\"echo hello\\\"'")
  end

  it "runs command with umask" do
    cmd = TTY::Command::Cmd.new(:echo, "hello", umask: "077")
    expect(cmd.to_command).to eq("umask 077 && echo hello")
  end

  it "runs command with umask, chdir" do
    cmd = TTY::Command::Cmd.new(:echo, "hello", umask: "077", chdir: "/tmp")
    expect(cmd.to_command).to eq("cd /tmp && umask 077 && echo hello")
  end

  it "runs command with umask, chdir & user" do
    cmd = TTY::Command::Cmd.new(:echo, "hello", umask: "077", chdir: "/tmp", user: "piotrmurach")
    expect(cmd.to_command).to eq("cd /tmp && umask 077 && sudo -u piotrmurach -- sh -c 'echo hello'")
  end

  it "runs command with umask, user, chdir and env" do
    cmd = TTY::Command::Cmd.new(:echo, "hello", umask: "077", chdir: "/tmp", user: "piotrmurach", env: { foo: "bar" })
    expect(cmd.to_command).to eq(%{cd /tmp && umask 077 && ( export FOO=\"bar\" ; sudo -u piotrmurach FOO=\"bar\" -- sh -c 'echo hello' )})
  end

  it "provides unique identifier" do
    cmd = TTY::Command::Cmd.new(:echo, "hello")
    expect(cmd.uuid).to match(/^\w{8}$/)
  end

  it "converts command to hash" do
    cmd = TTY::Command::Cmd.new(:echo, "hello")
    expect(cmd.to_hash).to include({
      command: "echo",
      argv: ["hello"]
    })
  end

  it "escapes arguments that need escaping" do
    cmd = TTY::Command::Cmd.new(:echo, "hello world")
    expect(cmd.to_hash).to include({
      command: "echo",
      argv: ["hello\\ world"]
    })
  end

  it "escapes special characters in split arguments" do
    args = %w(git for-each-ref --format='%(refname)' refs/heads/)
    cmd = TTY::Command::Cmd.new(*args)
    expect(cmd.to_hash).to include({
      command: "git",
      argv: ["for-each-ref", "--format\\=\\'\\%\\(refname\\)\\'", "refs/heads/"]
    })
  end

  it "updates command options with global only when not already present" do
    cmd_options = { env: { foo: "a" }, out: $stdout }
    cmd = TTY::Command::Cmd.new(:echo, "hello", cmd_options)
    expect(cmd.options).to eq(cmd_options)

    cmd.update({ verbose: true, env: { bar: "b" } })

    expect(cmd.options).to eq({
      env: { foo: "a" },
      out: $stdout,
      verbose: true
    })
  end
end