webbynode 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of webbynode might be problematic. Click here for more details.

Files changed (98) hide show
  1. data/Manifest +88 -4
  2. data/PostInstall.txt +42 -9
  3. data/README.rdoc +6 -0
  4. data/Rakefile +16 -19
  5. data/assets/webbynode.png +0 -0
  6. data/bin/webbynode +3 -3
  7. data/bin/wn +7 -0
  8. data/cucumber.yml +1 -0
  9. data/devver.rake +174 -0
  10. data/features/bootstrap.feature +17 -0
  11. data/features/step_definitions/command_steps.rb +14 -0
  12. data/features/support/env.rb +22 -0
  13. data/features/support/hooks.rb +8 -0
  14. data/{test/test_webbynode.rb → features/support/io_features.rb} +0 -0
  15. data/features/support/mocha.rb +15 -0
  16. data/lib/templates/api_token +14 -0
  17. data/lib/templates/backup +15 -0
  18. data/lib/templates/gitignore +4 -0
  19. data/lib/templates/help +53 -0
  20. data/lib/webbynode/api_client.rb +121 -0
  21. data/lib/webbynode/application.rb +21 -0
  22. data/lib/webbynode/command.rb +332 -0
  23. data/lib/webbynode/commands/add_backup.rb +33 -0
  24. data/lib/webbynode/commands/add_key.rb +24 -0
  25. data/lib/webbynode/commands/alias.rb +153 -0
  26. data/lib/webbynode/commands/change_dns.rb +29 -0
  27. data/lib/webbynode/commands/config.rb +15 -0
  28. data/lib/webbynode/commands/delete.rb +25 -0
  29. data/lib/webbynode/commands/help.rb +25 -0
  30. data/lib/webbynode/commands/init.rb +77 -0
  31. data/lib/webbynode/commands/push.rb +70 -0
  32. data/lib/webbynode/commands/remote.rb +28 -0
  33. data/lib/webbynode/commands/restart.rb +25 -0
  34. data/lib/webbynode/commands/start.rb +23 -0
  35. data/lib/webbynode/commands/stop.rb +23 -0
  36. data/lib/webbynode/commands/tasks.rb +149 -0
  37. data/lib/webbynode/commands/version.rb +8 -0
  38. data/lib/webbynode/commands/webbies.rb +30 -0
  39. data/lib/webbynode/git.rb +112 -0
  40. data/lib/webbynode/io.rb +175 -0
  41. data/lib/webbynode/notify.rb +19 -0
  42. data/lib/webbynode/option.rb +84 -0
  43. data/lib/webbynode/parameter.rb +27 -0
  44. data/lib/webbynode/properties.rb +43 -0
  45. data/lib/webbynode/push_and.rb +16 -0
  46. data/lib/webbynode/remote_executor.rb +21 -0
  47. data/lib/webbynode/server.rb +39 -0
  48. data/lib/webbynode/ssh.rb +65 -0
  49. data/lib/webbynode/ssh_keys.rb +36 -0
  50. data/lib/webbynode.rb +56 -0
  51. data/spec/fixtures/aliases +0 -0
  52. data/spec/fixtures/api/credentials +3 -0
  53. data/spec/fixtures/api/dns +30 -0
  54. data/spec/fixtures/api/dns_a_record +20 -0
  55. data/spec/fixtures/api/dns_a_record_already_exists +15 -0
  56. data/spec/fixtures/api/dns_a_record_error +13 -0
  57. data/spec/fixtures/api/dns_new_zone +17 -0
  58. data/spec/fixtures/api/webbies +26 -0
  59. data/spec/fixtures/api/webbies_unauthorized +12 -0
  60. data/spec/fixtures/api/webby +6 -0
  61. data/spec/fixtures/commands/tasks/after_push +3 -0
  62. data/spec/fixtures/fixture_helpers +2 -0
  63. data/spec/fixtures/git/config/210.11.13.12 +9 -0
  64. data/spec/fixtures/git/config/67.23.79.31 +9 -0
  65. data/spec/fixtures/git/config/67.23.79.32 +9 -0
  66. data/spec/fixtures/git/config/config +9 -0
  67. data/spec/fixtures/git/status/clean +2 -0
  68. data/spec/fixtures/git/status/dirty +9 -0
  69. data/spec/fixtures/pushand +2 -0
  70. data/spec/spec_helper.rb +58 -0
  71. data/spec/webbynode/api_client_spec.rb +227 -0
  72. data/spec/webbynode/application_spec.rb +50 -0
  73. data/spec/webbynode/command_spec.rb +285 -0
  74. data/spec/webbynode/commands/add_backup_spec.rb +66 -0
  75. data/spec/webbynode/commands/add_key_spec.rb +58 -0
  76. data/spec/webbynode/commands/alias_spec.rb +213 -0
  77. data/spec/webbynode/commands/change_dns_spec.rb +51 -0
  78. data/spec/webbynode/commands/config_spec.rb +22 -0
  79. data/spec/webbynode/commands/delete_spec.rb +78 -0
  80. data/spec/webbynode/commands/help_spec.rb +43 -0
  81. data/spec/webbynode/commands/init_spec.rb +326 -0
  82. data/spec/webbynode/commands/push_spec.rb +175 -0
  83. data/spec/webbynode/commands/remote_spec.rb +76 -0
  84. data/spec/webbynode/commands/tasks_spec.rb +288 -0
  85. data/spec/webbynode/commands/version_spec.rb +18 -0
  86. data/spec/webbynode/commands/webbies_spec.rb +27 -0
  87. data/spec/webbynode/git_spec.rb +310 -0
  88. data/spec/webbynode/io_spec.rb +198 -0
  89. data/spec/webbynode/option_spec.rb +48 -0
  90. data/spec/webbynode/parameter_spec.rb +70 -0
  91. data/spec/webbynode/push_and_spec.rb +28 -0
  92. data/spec/webbynode/remote_executor_spec.rb +25 -0
  93. data/spec/webbynode/server_spec.rb +101 -0
  94. data/webbynode.gemspec +25 -16
  95. metadata +182 -14
  96. data/lib/wn.rb +0 -106
  97. data/test/test_helper.rb +0 -9
  98. data/test/test_wn.rb +0 -220
@@ -0,0 +1,26 @@
1
+ HTTP/1.1 200 OK
2
+ Server: nginx/0.5.33
3
+ Date: Tue, 19 Jan 2010 18:49:34 GMT
4
+ Content-Type: text/yaml; charset=utf-8
5
+ Connection: keep-alive
6
+ Set-Cookie: _webbymanager_session=BAh7BjoPc2Vzc2lvbl9pZCIlYjA3M2Y0MDYwNjM4MjM2ZWMxY2E0ZTlmMWE5OGI4MTg%3D--67402230568aa8e5cf60775185b3235785584eef; path=/; HttpOnly
7
+ Status: 200
8
+ ETag: "07d4dbf860b002d75b666bbbbede61c0"
9
+ X-Runtime: 2842
10
+ Cache-Control: private, max-age=0, must-revalidate
11
+ Content-Length: 222
12
+
13
+ ---
14
+ webbies:
15
+ - :ip: 201.81.121.201
16
+ :status: "on"
17
+ :name: sandbox
18
+ :notes:
19
+ :plan: Webbybeta
20
+ :node: miami-b15
21
+ - :ip: 61.21.71.31
22
+ :status: "on"
23
+ :name: webby3067
24
+ :notes:
25
+ :plan: Webbybeta
26
+ :node: miami-b02
@@ -0,0 +1,12 @@
1
+ HTTP/1.1 401 Unauthorized
2
+ Server: nginx/0.6.35
3
+ Date: Sat, 30 Jan 2010 19:01:57 GMT
4
+ Content-Type: text/html; charset=utf-8
5
+ Connection: keep-alive
6
+ Set-Cookie: _webbymanager_session=BAh7BjoPc2Vzc2lvbl9pZCIlOTRjZWZkOTZhODA0ZGViNWJkZDZhYWNjYmQxYTI2YzE%3D--ff4fd42ef26eef03c132238e9b472bc8f33080de; path=/; HttpOnly
7
+ Status: 401
8
+ X-Runtime: 75
9
+ Cache-Control: no-cache
10
+ Content-Length: 13
11
+
12
+ Unauthorized
@@ -0,0 +1,6 @@
1
+ - testwebby
2
+ - ip: 201.81.121.201
3
+ status: "on"
4
+ notes:
5
+ plan: Webbybeta
6
+ node: miami-b15
@@ -0,0 +1,3 @@
1
+ rake db:migrate RAILS_ENV=production
2
+ rake db:seed
3
+ rake db:create RAILS_ENV=test
@@ -0,0 +1,2 @@
1
+ #! /bin/bash
2
+ curl -is -F "email=$1" -F "token=$2" https://manager.webbynode.com/api/yaml/webbies > spec/fixtures/api/webbies
@@ -0,0 +1,9 @@
1
+ [core]
2
+ repositoryformatversion = 0
3
+ filemode = true
4
+ bare = false
5
+ logallrefupdates = true
6
+ ignorecase = true
7
+ [remote "webbynode"]
8
+ url = git@210.11.13.12:myapp
9
+ fetch = +refs/heads/*:refs/remotes/webbynode/*
@@ -0,0 +1,9 @@
1
+ [core]
2
+ repositoryformatversion = 0
3
+ filemode = true
4
+ bare = false
5
+ logallrefupdates = true
6
+ ignorecase = true
7
+ [remote "webbynode"]
8
+ url = git@67.23.79.31:myapp
9
+ fetch = +refs/heads/*:refs/remotes/webbynode/*
@@ -0,0 +1,9 @@
1
+ [core]
2
+ repositoryformatversion = 0
3
+ filemode = true
4
+ bare = false
5
+ logallrefupdates = true
6
+ ignorecase = true
7
+ [remote "webbynode"]
8
+ url = git@67.23.79.32:myapp
9
+ fetch = +refs/heads/*:refs/remotes/webbynode/*
@@ -0,0 +1,9 @@
1
+ [core]
2
+ repositoryformatversion = 0
3
+ filemode = true
4
+ bare = false
5
+ logallrefupdates = true
6
+ ignorecase = true
7
+ [remote "webbynode"]
8
+ url = git@1.2.3.4:webbynode
9
+ fetch = +refs/heads/*:refs/remotes/webbynode/*
@@ -0,0 +1,2 @@
1
+ # On branch master
2
+ nothing to commit (working directory clean)
@@ -0,0 +1,9 @@
1
+ # On branch master
2
+ # Changed but not updated:
3
+ # (use "git add <file>..." to update what will be committed)
4
+ # (use "git checkout -- <file>..." to discard changes in working directory)
5
+ #
6
+ # modified: lib/webbynode/git.rb
7
+ # modified: spec/webbynode/git_spec.rb
8
+ #
9
+ no changes added to commit (use "git add" and/or "git commit -a")
@@ -0,0 +1,2 @@
1
+ #! /bin/bash
2
+ phd $0 test.webbynode.com
@@ -0,0 +1,58 @@
1
+ # Require RSpec
2
+ require 'rubygems'
3
+ require 'spec'
4
+ require 'pp'
5
+ begin
6
+ require 'fakeweb'
7
+ rescue LoadError
8
+ puts "Missing gem fakeweb, required for testing."
9
+ puts "Run:"
10
+ puts " sudo gem install fakeweb"
11
+ exit
12
+ end
13
+
14
+ # Load Webbynode Class
15
+ require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib', 'webbynode')
16
+
17
+ # Set Testing Environment
18
+ $testing = true
19
+ FakeWeb.allow_net_connect = false
20
+
21
+ # Helper Methods
22
+ module Webbynode::IoStub
23
+ def stdout
24
+ $stdout.rewind
25
+ $stdout.read
26
+ end
27
+
28
+ def debug(s)
29
+ @orig_stdout.puts s
30
+ end
31
+ end
32
+
33
+ # Reads out a file from the fixtures directory
34
+ def read_fixture(file)
35
+ File.read(File.join(File.dirname(__FILE__), "fixtures", file))
36
+ end
37
+
38
+ module Kernel
39
+ def ask(*params)
40
+ raise "Unexpected ask with: #{params.inspect}"
41
+ end
42
+
43
+ def d(x); $stderr.puts x; end
44
+ def ppd(x); $stderr.puts x.pretty_inspect; end
45
+ end
46
+
47
+ Spec::Runner.configure do |config|
48
+ config.include Webbynode::IoStub
49
+
50
+ config.before(:each) do
51
+ @orig_stdout = $stdout
52
+ $stdout = StringIO.new
53
+ end
54
+
55
+ config.after(:each) do
56
+ $stdout = @orig_stdout
57
+ end
58
+ end
@@ -0,0 +1,227 @@
1
+ # Load Spec Helper
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
3
+
4
+ describe Webbynode::ApiClient do
5
+ let(:base_uri) { Webbynode::ApiClient.base_uri }
6
+ let(:api) { Webbynode::ApiClient.new }
7
+
8
+ before(:each) do
9
+ FakeWeb.clean_registry
10
+ end
11
+
12
+ describe "#create_record" do
13
+ it "should raise an exception if the domain is inactive" do
14
+ api.should_receive(:zones).and_return({"another.com." => {:id => 21, :status => "Inactive"}})
15
+ api.should_receive(:create_zone).never
16
+ api.should_receive(:create_a_record).never
17
+
18
+ lambda { api.create_record("yes.another.com", "10.0.0.0") }.should raise_error(Webbynode::ApiClient::InactiveZone, "another.com.")
19
+ end
20
+
21
+ it "should create the domain, when inexistent" do
22
+ api.should_receive(:zones).and_return({})
23
+ api.should_receive(:create_zone).with("newdomain.com.").and_return({:id => 20, :status => 'Active'})
24
+ api.should_receive(:create_a_record).with(20, "new", "212.10.20.10", "new.newdomain.com")
25
+
26
+ api.create_record("new.newdomain.com", "212.10.20.10")
27
+ end
28
+
29
+ it "should retrieve the domains, when inexistent" do
30
+ api.should_receive(:zones).and_return({"mydomain.com.br." => {:id => 21, :status => 'Active'}})
31
+ api.should_receive(:create_a_record).with(21, "new", "212.10.20.10", "new.mydomain.com.br")
32
+
33
+ api.create_record("new.mydomain.com.br", "212.10.20.10")
34
+ end
35
+ end
36
+
37
+ describe "#zones" do
38
+ it "should return all the zones" do
39
+ FakeWeb.register_uri(:post, "#{Webbynode::ApiClient.base_uri}/dns",
40
+ :email => "fcoury@me.com", :response => read_fixture("api/dns"))
41
+
42
+ api.should_receive(:init_credentials).and_return({:email => "fcoury@me.com", :token => "apitoken"})
43
+ api.zones["rubyista.info."][:domain].should == "rubyista.info."
44
+ api.zones["webbyapp.com."][:domain].should == "webbyapp.com."
45
+ end
46
+ end
47
+
48
+ describe "#create_zone" do
49
+ it "should create a new zone and a new A record" do
50
+ FakeWeb.register_uri(:post, "#{Webbynode::ApiClient.base_uri}/dns",
51
+ :email => "fcoury@me.com", :response => read_fixture("api/dns"))
52
+
53
+ FakeWeb.register_uri(:post,
54
+ "#{Webbynode::ApiClient.base_uri}/dns/new?zone[ttl]=86400&zone[domain]=newzone.com.",
55
+ :email => "fcoury@me.com", :response => read_fixture("api/dns_new_zone"))
56
+
57
+ api.should_receive(:init_credentials).and_return({:email => "fcoury@me.com", :token => "apitoken"})
58
+ api.create_zone("newzone.com.")[:id].should == 1045
59
+ end
60
+ end
61
+
62
+ describe "#create_a_record" do
63
+ it "should create a new A record" do
64
+ FakeWeb.register_uri(:post, "#{Webbynode::ApiClient.base_uri}/dns",
65
+ :email => "fcoury@me.com", :response => read_fixture("api/dns"))
66
+
67
+ FakeWeb.register_uri(:post,
68
+ "#{Webbynode::ApiClient.base_uri}/dns/14/records/new?record[data]=200.100.200.100&record[type]=A&record[name]=xyz",
69
+ :email => "fcoury@me.com", :response => read_fixture("api/dns_a_record"))
70
+
71
+ api.should_receive(:init_credentials).and_return({:email => "fcoury@me.com", :token => "apitoken"})
72
+ api.create_a_record(14, "xyz", "200.100.200.100", "xyz.rubyista.info")[:id].should == 7360
73
+ end
74
+
75
+ it "raise an exception upon errors" do
76
+ FakeWeb.register_uri(:post, "#{Webbynode::ApiClient.base_uri}/dns",
77
+ :email => "fcoury@me.com", :response => read_fixture("api/dns"))
78
+
79
+ FakeWeb.register_uri(:post, "#{Webbynode::ApiClient.base_uri}/dns/14/records/new?record[data]=200.100.200.100&record[type]=A&record[name]=xyz",
80
+ :email => "fcoury@me.com", :response => read_fixture("api/dns_a_record_error"))
81
+
82
+ api.should_receive(:init_credentials).and_return({:email => "fcoury@me.com", :token => "apitoken"})
83
+ lambda {
84
+ api.create_a_record(14, "xyz", "200.100.200.100", "xyz.rubyista.info")
85
+ }.should raise_error(Webbynode::ApiClient::ApiError, "No DNS entry for id 99999")
86
+ end
87
+ end
88
+
89
+ describe "#ip_for" do
90
+ describe "when file ~/.webbynode is absent" do
91
+ it "should call init_credentials email address and API token" do
92
+ FakeWeb.register_uri(:post, "#{base_uri}/webbies",
93
+ :email => "fcoury@me.com", :response => read_fixture("api/webbies"))
94
+
95
+ api.should_receive(:init_credentials).and_return({:email => "fcoury@me.com", :token => "apitoken"})
96
+ api.ip_for("webby3067").should == "61.21.71.31"
97
+ end
98
+
99
+ it "should return the correct ip" do
100
+ FakeWeb.register_uri(:post, "#{base_uri}/webbies",
101
+ :email => "fcoury@me.com", :response => read_fixture("api/webbies"))
102
+
103
+ api.should_receive(:init_credentials).and_return({:email => "fcoury@me.com", :token => "apitoken"})
104
+ api.ip_for("sandbox").should == "201.81.121.201"
105
+ end
106
+ end
107
+
108
+ describe "when file ~/.webbynode is present" do
109
+ before do
110
+ FakeWeb.register_uri(:post, "#{base_uri}/webbies",
111
+ :email => "fcoury@me.com", :response => read_fixture("api/webbies"))
112
+ end
113
+
114
+ it "should return the IP for existing Webby hostname" do
115
+ api.should_receive(:credentials).and_return({:email => "fcoury@me.com", :token => "apitoken"})
116
+ api.ip_for("sandbox").should == "201.81.121.201"
117
+ end
118
+
119
+ it "should show an error message if the Webby does not exist for the user" do
120
+ api.should_receive(:credentials).and_return({:email => "fcoury@me.com", :token => "apitoken"})
121
+ api.ip_for("this_doesnt_exist").nil?.should == true
122
+ end
123
+ end
124
+ end
125
+
126
+ describe "when unauthorized" do
127
+ it "should raise an error" do
128
+ FakeWeb.register_uri(:post, "#{base_uri}/webbies",
129
+ :email => "fcoury@me.com", :response => read_fixture("api/webbies_unauthorized"))
130
+
131
+ api = Webbynode::ApiClient.new
132
+ api.should_receive(:credentials).and_return({:email => "fcoury@me.com"})
133
+ lambda { api.ip_for("sandbox") }.should raise_error(Webbynode::ApiClient::Unauthorized, "You have provided the wrong credentials")
134
+ end
135
+ end
136
+
137
+ describe "#init_credentials" do
138
+ let(:io) { double("Io") }
139
+
140
+ before(:each) do
141
+ api.should_receive(:io).any_number_of_times.and_return(io)
142
+ end
143
+
144
+ context "when credentials file exists" do
145
+ it "should read the credentials" do
146
+ io.should_receive(:file_exists?).with("#{ENV['HOME']}/.webbynode").and_return(true)
147
+ api.should_receive(:properties).and_return({:email => "fcoury@me.com", :token => "apitoken"})
148
+
149
+ creds = api.init_credentials
150
+ creds[:email].should == "fcoury@me.com"
151
+ creds[:token].should == "apitoken"
152
+ end
153
+
154
+ it "should write the credentials if force is true" do
155
+ FakeWeb.register_uri(:post, "#{base_uri}/webbies",
156
+ :email => "fcoury@me.com", :response => read_fixture("api/webbies"))
157
+
158
+ properties = {}
159
+ properties.should_receive(:save)
160
+
161
+ io.should_receive(:file_exists?).with("#{ENV['HOME']}/.webbynode").and_return(true)
162
+ io.should_receive(:read_from_template)
163
+ api.should_receive(:properties).any_number_of_times.and_return(properties)
164
+
165
+ api.should_receive(:ask).with("Login email: ").once.ordered.and_return("login@email.com")
166
+ api.should_receive(:ask).with("API token: ").once.ordered.and_return("apitoken")
167
+
168
+ creds = api.init_credentials(true)
169
+ creds[:email].should == "login@email.com"
170
+ creds[:token].should == "apitoken"
171
+ end
172
+
173
+ it "should not prompt and write the credentials if force is a Hash" do
174
+ FakeWeb.register_uri(:post, "#{base_uri}/webbies",
175
+ :email => "fcoury@me.com", :response => read_fixture("api/webbies"))
176
+
177
+ properties = {}
178
+ properties.should_receive(:save)
179
+
180
+ io.should_receive(:file_exists?).with("#{ENV['HOME']}/.webbynode").and_return(true)
181
+ api.should_receive(:properties).any_number_of_times.and_return(properties)
182
+
183
+ api.should_receive(:ask).never
184
+
185
+ creds = api.init_credentials({ :email => 'login@email.com', :token => 'apitoken' })
186
+ creds[:email].should == "login@email.com"
187
+ creds[:token].should == "apitoken"
188
+ end
189
+ end
190
+
191
+ context "when credentials doesn't exist" do
192
+ it "should input the credentials" do
193
+ FakeWeb.register_uri(:post, "#{base_uri}/webbies",
194
+ :email => "fcoury@me.com", :response => read_fixture("api/webbies"))
195
+
196
+ properties = {}
197
+ properties.should_receive(:save)
198
+
199
+ io.should_receive(:file_exists?).with("#{ENV['HOME']}/.webbynode").and_return(false)
200
+ io.should_receive(:read_from_template)
201
+ api.should_receive(:properties).any_number_of_times.and_return(properties)
202
+
203
+ api.should_receive(:ask).with("Login email: ").once.ordered.and_return("login@email.com")
204
+ api.should_receive(:ask).with("API token: ").once.ordered.and_return("apitoken")
205
+
206
+ api.init_credentials
207
+ end
208
+
209
+ it "should not write the file if credentials are wrong" do
210
+ FakeWeb.register_uri(:post, "#{base_uri}/webbies",
211
+ :email => "fcoury@me.com", :response => read_fixture("api/webbies_unauthorized"))
212
+
213
+ properties = {}
214
+ properties.should_receive(:save).never
215
+
216
+ io.should_receive(:file_exists?).with("#{ENV['HOME']}/.webbynode").and_return(false)
217
+ io.should_receive(:read_from_template)
218
+ api.should_receive(:properties).any_number_of_times.and_return(properties)
219
+
220
+ api.should_receive(:ask).with("Login email: ").once.ordered.and_return("login@email.com")
221
+ api.should_receive(:ask).with("API token: ").once.ordered.and_return("apitoken")
222
+
223
+ lambda { api.init_credentials }.should raise_error(Webbynode::ApiClient::Unauthorized, "You have provided the wrong credentials")
224
+ end
225
+ end
226
+ end
227
+ end
@@ -0,0 +1,50 @@
1
+ # Load Spec Helper
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
3
+
4
+ describe Webbynode::Application do
5
+ class TestCommand < Webbynode::Command
6
+ end
7
+
8
+ describe "running commands" do
9
+ it "should instantiate the class" do
10
+ cmd = mock("Init")
11
+ cmd.as_null_object
12
+
13
+ Webbynode::Commands::Init.should_receive(:new).and_return(cmd)
14
+ wn = Webbynode::Application.new("init")
15
+ wn.execute
16
+ end
17
+ end
18
+
19
+ describe "parsing commands" do
20
+ context "when class doesn't exist" do
21
+ it "should translate words separated by underscore into capitalized parts" do
22
+ Webbynode::Commands.should_receive(:const_get).and_raise(NameError)
23
+
24
+ cls = mock("UnknownClass")
25
+ cls.should_receive(:new).never
26
+
27
+ wn = Webbynode::Application.new("inexistent_command")
28
+ Webbynode::Command.should_receive(:puts).with('Command "inexistent_command" doesn\'t exist')
29
+
30
+ wn.should_receive(:command_class).never
31
+ wn.execute
32
+ end
33
+ end
34
+ end
35
+
36
+ describe "#execute" do
37
+ it "should run the command" do
38
+ cmd = double("CommandInstance")
39
+ cmd.should_receive(:run)
40
+ cmd.as_null_object
41
+
42
+ cmd_class = double("CommandClass")
43
+ cmd_class.should_receive(:new).and_return(cmd)
44
+
45
+ Webbynode::Commands.should_receive(:const_get).with("DoIt").and_return(cmd_class)
46
+ wn = Webbynode::Application.new("do_it")
47
+ wn.execute
48
+ end
49
+ end
50
+ end