vmc 0.5.0.beta.12 → 0.5.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/vmc/cli.rb +62 -24
- data/lib/vmc/cli/app/push.rb +23 -2
- data/lib/vmc/cli/app/push/create.rb +14 -7
- data/lib/vmc/cli/app/push/interactions.rb +10 -3
- data/lib/vmc/cli/app/push/sync.rb +4 -2
- data/lib/vmc/cli/app/stats.rb +1 -1
- data/lib/vmc/cli/route/map.rb +22 -16
- data/lib/vmc/cli/service/create.rb +19 -4
- data/lib/vmc/cli/start/info.rb +4 -0
- data/lib/vmc/cli/start/login.rb +4 -0
- data/lib/vmc/cli/start/logout.rb +4 -0
- data/lib/vmc/cli/user/base.rb +1 -1
- data/lib/vmc/test_support/command_helper.rb +7 -13
- data/lib/vmc/version.rb +1 -1
- data/spec/assets/specker_runner/specker_runner_input.rb +6 -0
- data/spec/assets/specker_runner/specker_runner_pause.rb +5 -0
- data/spec/console_app_specker/console_app_specker_matchers_spec.rb +152 -0
- data/spec/console_app_specker/specker_runner_spec.rb +157 -0
- data/spec/features/new_user_flow_spec.rb +83 -45
- data/spec/spec_helper.rb +16 -0
- data/spec/support/console_app_specker_matchers.rb +75 -0
- data/spec/support/specker_runner.rb +123 -0
- data/spec/vmc/cli/app/push/create_spec.rb +82 -21
- data/spec/vmc/cli/app/push_spec.rb +49 -4
- data/spec/vmc/cli/app/stats_spec.rb +1 -1
- data/spec/vmc/cli/route/map_spec.rb +38 -42
- data/spec/vmc/cli/start/info_spec.rb +21 -1
- data/spec/vmc/cli/start/login_spec.rb +36 -10
- data/spec/vmc/cli/start/logout_spec.rb +63 -0
- data/spec/vmc/cli/user/passwd_spec.rb +1 -1
- data/spec/vmc/cli/user/register_spec.rb +1 -1
- data/spec/vmc/cli_spec.rb +243 -33
- metadata +68 -36
data/lib/vmc/cli/user/base.rb
CHANGED
@@ -19,7 +19,7 @@ module VMC
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def validate_password_strength!(password)
|
22
|
-
strength = client.
|
22
|
+
strength = client.password_score(password)
|
23
23
|
msg = "Your password strength is: #{strength}"
|
24
24
|
fail msg if strength == :weak
|
25
25
|
line msg
|
@@ -1,28 +1,22 @@
|
|
1
1
|
module VMC::TestSupport::CommandHelper
|
2
2
|
def vmc(argv)
|
3
|
+
Mothership.new.exit_status 0
|
3
4
|
stub(VMC::CLI).exit { |code| code }
|
4
5
|
capture_output { VMC::CLI.start(argv + ["--debug"]) }
|
5
6
|
end
|
6
7
|
|
7
|
-
def
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
print_debug_output if status == 0
|
14
|
-
expect(status).to eq 1
|
8
|
+
def expect_status_and_output(status = 0, out = "", err = "")
|
9
|
+
expect([
|
10
|
+
status,
|
11
|
+
stdout.string.strip_progress_dots,
|
12
|
+
stderr.string.strip_progress_dots
|
13
|
+
]).to eq([status, out, err])
|
15
14
|
end
|
16
15
|
|
17
16
|
def bool_flag(flag)
|
18
17
|
"#{'no-' unless send(flag)}#{flag.to_s.gsub('_', '-')}"
|
19
18
|
end
|
20
19
|
|
21
|
-
def print_debug_output
|
22
|
-
puts stdout.string.strip_progress_dots
|
23
|
-
puts stderr.string
|
24
|
-
end
|
25
|
-
|
26
20
|
attr_reader :stdout, :stderr, :status
|
27
21
|
|
28
22
|
def capture_output
|
data/lib/vmc/version.rb
CHANGED
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
include ConsoleAppSpeckerMatchers
|
3
|
+
|
4
|
+
describe ConsoleAppSpeckerMatchers, :ruby19 => true do
|
5
|
+
describe "#say" do
|
6
|
+
it "returns an ExpectOutputMatcher" do
|
7
|
+
say("").should be_a(ExpectOutputMatcher)
|
8
|
+
end
|
9
|
+
|
10
|
+
context "with an explicit timeout" do
|
11
|
+
it "returns an ExpectOutputMatcher" do
|
12
|
+
matcher = say("", 30)
|
13
|
+
matcher.should be_a(ExpectOutputMatcher)
|
14
|
+
matcher.timeout.should == 30
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#have_exited_with" do
|
20
|
+
it "returns an ExitCodeMatcher" do
|
21
|
+
have_exited_with(1).should be_a(ExitCodeMatcher)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "has synonyms" do
|
25
|
+
exit_with(1).should be_a(ExitCodeMatcher)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe ExpectOutputMatcher, :ruby19 => true do
|
31
|
+
let(:expected_output) { "expected_output" }
|
32
|
+
let(:timeout) { 1 }
|
33
|
+
|
34
|
+
subject { ExpectOutputMatcher.new(expected_output, timeout) }
|
35
|
+
|
36
|
+
describe "#matches?" do
|
37
|
+
context "with something that isn't a runner" do
|
38
|
+
it "raises an exception" do
|
39
|
+
expect {
|
40
|
+
subject.matches?("c'est ne pas une specker runner")
|
41
|
+
}.to raise_exception(InvalidInputError)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "with a valid runner" do
|
46
|
+
context "when the expected output is in the process output" do
|
47
|
+
it "finds the expected output" do
|
48
|
+
run("echo -n expected_output") do |runner|
|
49
|
+
subject.matches?(runner).should be_true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when the expected output is not in the process output" do
|
55
|
+
let(:runner) { SpeckerRunner.new('echo -n not_what_we_were_expecting') }
|
56
|
+
|
57
|
+
it "does not find the expected output" do
|
58
|
+
run("echo -n not_what_we_were_expecting") do |runner|
|
59
|
+
subject.matches?(runner).should be_false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "failure messages" do
|
67
|
+
it "has a correct failure message" do
|
68
|
+
run("echo -n actual_output") do |runner|
|
69
|
+
subject.matches?(runner)
|
70
|
+
subject.failure_message.should == "expected 'expected_output' to be printed, but it wasn't. full output:\nactual_output"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it "has a correct negative failure message" do
|
75
|
+
run("echo -n actual_output") do |runner|
|
76
|
+
subject.matches?(runner)
|
77
|
+
subject.negative_failure_message.should == "expected 'expected_output' to not be printed, but it was. full output:\nactual_output"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe ExitCodeMatcher, :ruby19 => true do
|
84
|
+
let(:expected_code) { 0 }
|
85
|
+
|
86
|
+
subject { ExitCodeMatcher.new(expected_code) }
|
87
|
+
|
88
|
+
describe "#matches?" do
|
89
|
+
context "with something that isn't a runner" do
|
90
|
+
it "raises an exception" do
|
91
|
+
expect {
|
92
|
+
subject.matches?("c'est ne pas une specker runner")
|
93
|
+
}.to raise_exception(InvalidInputError)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "with a valid runner" do
|
98
|
+
context "and the command exited with the expected exit code" do
|
99
|
+
it "returns true" do
|
100
|
+
run("true") do |runner|
|
101
|
+
subject.matches?(runner).should be_true
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "and the command exits with a different exit code" do
|
107
|
+
it "returns false" do
|
108
|
+
run("false") do |runner|
|
109
|
+
subject.matches?(runner).should be_false
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context "and the command runs for a while" do
|
115
|
+
it "waits for it to exit" do
|
116
|
+
run("sleep 0.5") do |runner|
|
117
|
+
subject.matches?(runner).should be_true
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "failure messages" do
|
125
|
+
context "with a command that's exited" do
|
126
|
+
it "has a correct failure message" do
|
127
|
+
run("false") do |runner|
|
128
|
+
subject.matches?(runner)
|
129
|
+
runner.wait_for_exit
|
130
|
+
subject.failure_message.should == "expected process to exit with status 0, but it exited with status 1"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
it "has a correct negative failure message" do
|
135
|
+
run("false") do |runner|
|
136
|
+
subject.matches?(runner)
|
137
|
+
runner.wait_for_exit
|
138
|
+
subject.negative_failure_message.should == "expected process to not exit with status 0, but it did"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context "with a command that's still running" do
|
144
|
+
it "waits for it to exit" do
|
145
|
+
run("ruby -e 'sleep 1; exit 1'") do |runner|
|
146
|
+
subject.matches?(runner)
|
147
|
+
subject.failure_message.should == "expected process to exit with status 0, but it exited with status 1"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SpeckerRunner, :ruby19 => true do
|
4
|
+
def asset(file)
|
5
|
+
File.expand_path("../../assets/specker_runner/#{file}", __FILE__)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:timeout) { 1 }
|
9
|
+
|
10
|
+
describe "running a command" do
|
11
|
+
let(:file) do
|
12
|
+
file = Tempfile.new('test-specker-runner')
|
13
|
+
sleep 1 # wait one second to make sure touching the file does something measurable
|
14
|
+
file
|
15
|
+
end
|
16
|
+
|
17
|
+
after { file.unlink }
|
18
|
+
|
19
|
+
it "runs a command" do
|
20
|
+
run("touch -a #{file.path}") do |runner|
|
21
|
+
runner.wait_for_exit
|
22
|
+
file.stat.atime.should > file.stat.mtime
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#expect" do
|
28
|
+
context "when the expected output shows up" do
|
29
|
+
it "returns a truthy value" do
|
30
|
+
run("echo -n foo") do |runner|
|
31
|
+
expect(runner.expect('foo')).to be_true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when the expected output never shows up" do
|
37
|
+
it "returns nil" do
|
38
|
+
run("echo the spanish inquisition") do |runner|
|
39
|
+
expect(runner.expect("something else", 0.5)).to be_nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "when the output eventually shows up" do
|
45
|
+
it "returns a truthy value" do
|
46
|
+
run("ruby #{asset("specker_runner_pause.rb")}") do |runner|
|
47
|
+
expect(runner.expect("finished")).to be_true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "backspace" do
|
53
|
+
it "respects the backspace character" do
|
54
|
+
run("ruby -e 'puts \"foo a\\bbar\"'") do |runner|
|
55
|
+
expect(runner.expect("foo bar")).to be_true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it "does not go beyond the beginning of the line" do
|
60
|
+
run("ruby -e 'print \"foo abc\nx\\b\\bd\"'") do |runner|
|
61
|
+
expect(runner.expect("foo abc\nd")).to be_true
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it "does not go beyond the beginning of the string" do
|
66
|
+
run("ruby -e 'print \"f\\b\\bbar\"'") do |runner|
|
67
|
+
expect(runner.expect("bar")).to be_true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it "leaves backspaced characters in the buffer until they're overwritten" do
|
72
|
+
run("ruby -e 'print \"foo abc\\b\\bd\"'") do |runner|
|
73
|
+
expect(runner.expect("foo adc")).to be_true
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "ansi escape sequences" do
|
79
|
+
it "filters ansi color sequences" do
|
80
|
+
run("ruby -e 'puts \"\\e[36mblue\\e[0m thing\"'") do |runner|
|
81
|
+
expect(runner.expect("blue thing")).to be_true
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "expecting multiple branches" do
|
87
|
+
context "and one of them matches" do
|
88
|
+
it "can be passed a hash of values with callbacks" do
|
89
|
+
run("echo 1 3") do |runner|
|
90
|
+
branches = {
|
91
|
+
"1" => proc { 1 },
|
92
|
+
"2" => proc { 2 },
|
93
|
+
"3" => proc { 3 }
|
94
|
+
}
|
95
|
+
|
96
|
+
expect(runner.expect(branches)).to eq 1
|
97
|
+
expect(runner.expect(branches)).to eq 3
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context "and none of them match" do
|
103
|
+
it "returns nil when none of the branches match" do
|
104
|
+
run("echo not_a_number") do |runner|
|
105
|
+
expect(runner.expect({"1" => proc { 1 }}, timeout)).to be_nil
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "#output" do
|
113
|
+
it "makes the entire command output (so far) available" do
|
114
|
+
run("echo 0 1 2 3") do |runner|
|
115
|
+
runner.expect("1")
|
116
|
+
runner.expect("3")
|
117
|
+
expect(runner.output).to eq "0 1 2 3"
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "#send_keys" do
|
124
|
+
it "sends input and expects more output afterward" do
|
125
|
+
run("ruby #{asset("specker_runner_input.rb")}") do |runner|
|
126
|
+
expect(runner.expect("started")).to be_true
|
127
|
+
runner.send_keys("foo")
|
128
|
+
expect(runner.expect("foo")).to be_true
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "#exit_code" do
|
134
|
+
it "returns the exit code" do
|
135
|
+
run("ruby -e 'exit 42'") do |runner|
|
136
|
+
runner.wait_for_exit
|
137
|
+
expect(runner.exit_code).to eq(42)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context "when the command is still running" do
|
142
|
+
it "waits for the command to exit" do
|
143
|
+
run("sleep 0.5") do |runner|
|
144
|
+
expect(runner.exit_code).to eq(0)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context "#exited?" do
|
151
|
+
it "returns false if the command is still running" do
|
152
|
+
run("sleep 10") do |runner|
|
153
|
+
expect(runner.exited?).to eq false
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -1,8 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require "webmock/rspec"
|
3
3
|
|
4
|
+
INTEGRATE_WITH = ENV["INTEGRATE_WITH"] || "default"
|
5
|
+
|
4
6
|
if ENV['VMC_TEST_USER'] && ENV['VMC_TEST_PASSWORD'] && ENV['VMC_TEST_TARGET']
|
5
|
-
describe 'A new user tries to use VMC against v1 production' do
|
7
|
+
describe 'A new user tries to use VMC against v1 production', :ruby19 => true do
|
8
|
+
include ConsoleAppSpeckerMatchers
|
9
|
+
include VMC::Interactive
|
10
|
+
|
6
11
|
let(:target) { ENV['VMC_TEST_TARGET'] }
|
7
12
|
let(:username) { ENV['VMC_TEST_USER'] }
|
8
13
|
let(:password) { ENV['VMC_TEST_PASSWORD'] }
|
@@ -15,61 +20,94 @@ if ENV['VMC_TEST_USER'] && ENV['VMC_TEST_PASSWORD'] && ENV['VMC_TEST_TARGET']
|
|
15
20
|
end
|
16
21
|
|
17
22
|
before do
|
18
|
-
FileUtils.rm_rf VMC::CONFIG_DIR
|
23
|
+
FileUtils.rm_rf File.expand_path(VMC::CONFIG_DIR)
|
19
24
|
WebMock.allow_net_connect!
|
25
|
+
Interact::Progress::Dots.start!
|
26
|
+
end
|
27
|
+
|
28
|
+
after do
|
29
|
+
vmc %W(delete #{app} -f --no-script)
|
30
|
+
Interact::Progress::Dots.stop!
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:vmc_bin) do
|
34
|
+
vmc = File.expand_path("#{SPEC_ROOT}/../bin/vmc.dev")
|
35
|
+
if INTEGRATE_WITH != 'default'
|
36
|
+
"rvm #{INTEGRATE_WITH}@vmc do #{vmc}"
|
37
|
+
else
|
38
|
+
vmc
|
39
|
+
end
|
20
40
|
end
|
21
41
|
|
22
|
-
|
42
|
+
it 'pushes a simple sinatra app using defaults as much as possible' do
|
43
|
+
run("#{vmc_bin} target http://#{target}") do |runner|
|
44
|
+
expect(runner).to say %r{Setting target to http://#{target}... OK}
|
45
|
+
end
|
46
|
+
|
47
|
+
run("#{vmc_bin} login") do |runner|
|
48
|
+
expect(runner).to say %r{target: https?://#{target}}
|
23
49
|
|
24
|
-
|
25
|
-
|
26
|
-
expect_success
|
27
|
-
expect(stdout.string.strip_progress_dots).to eq <<-OUT.strip_heredoc
|
28
|
-
Setting target to https://#{target}... OK
|
29
|
-
OUT
|
50
|
+
expect(runner).to say "Email>"
|
51
|
+
runner.send_keys username
|
30
52
|
|
31
|
-
|
32
|
-
|
33
|
-
expect(stdout.string.strip_progress_dots).to eq <<-OUT.strip_heredoc
|
34
|
-
target: https://#{target}
|
53
|
+
expect(runner).to say "Password>"
|
54
|
+
runner.send_keys password
|
35
55
|
|
36
|
-
Authenticating... OK
|
37
|
-
|
56
|
+
expect(runner).to say "Authenticating... OK"
|
57
|
+
end
|
38
58
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
Unknown app '#{app}'.
|
43
|
-
OUT
|
59
|
+
run("#{vmc_bin} app #{app}") do |runner|
|
60
|
+
expect(runner).to say "Unknown app '#{app}'."
|
61
|
+
end
|
44
62
|
|
45
63
|
Dir.chdir("#{SPEC_ROOT}/assets/hello-sinatra") do
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
64
|
+
run("#{vmc_bin} push") do |runner|
|
65
|
+
expect(runner).to say "Name>"
|
66
|
+
runner.send_keys app
|
67
|
+
|
68
|
+
expect(runner).to say "Instances> 1"
|
69
|
+
runner.send_keys ""
|
70
|
+
|
71
|
+
expect(runner).to say "1: sinatra"
|
72
|
+
expect(runner).to say "2: other"
|
73
|
+
expect(runner).to say "Framework> sinatra"
|
74
|
+
runner.send_keys ""
|
75
|
+
|
76
|
+
expect(runner).to say "1: ruby"
|
77
|
+
expect(runner).to say "Runtime>"
|
78
|
+
runner.send_keys "ruby19"
|
79
|
+
|
80
|
+
expect(runner).to say "1:"
|
81
|
+
expect(runner).to say "Memory Limit>"
|
82
|
+
runner.send_keys "64M"
|
83
|
+
|
84
|
+
expect(runner).to say "Creating #{app}... OK"
|
85
|
+
|
86
|
+
expect(runner).to say "1: #{app}."
|
87
|
+
expect(runner).to say "2: none"
|
88
|
+
expect(runner).to say "Domain>"
|
89
|
+
runner.send_keys ""
|
90
|
+
|
91
|
+
expect(runner).to say "Updating #{app}... OK"
|
92
|
+
|
93
|
+
expect(runner).to say "Create services for application?> n"
|
94
|
+
runner.send_keys ""
|
95
|
+
|
96
|
+
expect(runner).to say "Save configuration?> n"
|
97
|
+
runner.send_keys ""
|
98
|
+
|
99
|
+
expect(runner).to say "Uploading #{app}... OK"
|
100
|
+
expect(runner).to say "Starting #{app}... OK"
|
101
|
+
expect(runner).to say "Checking #{app}... OK", 30
|
102
|
+
end
|
66
103
|
end
|
67
104
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
105
|
+
run("#{vmc_bin} delete #{app}") do |runner|
|
106
|
+
expect(runner).to say "Really delete #{app}?>"
|
107
|
+
runner.send_keys "y"
|
108
|
+
|
109
|
+
expect(runner).to say "Deleting #{app}... OK"
|
110
|
+
end
|
73
111
|
end
|
74
112
|
end
|
75
113
|
else
|