plow 0.1.0

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.
@@ -0,0 +1,304 @@
1
+ # encoding: UTF-8
2
+
3
+ class Plow
4
+ class Strategy
5
+ class UbuntuHardy
6
+
7
+ ##
8
+ # Plowing strategy, compatible with the Linux Ubuntu Hardy Heron distribution, for generating
9
+ # a web-site within a user home directory.
10
+ class UserHomeWebApp
11
+ attr_reader :context, :users_file_path, :vhost_file_name, :vhost_file_path, :vhost_template_file_path
12
+ attr_reader :user_home_path, :sites_home_path, :app_root_path, :app_public_path, :app_log_path
13
+
14
+ ##
15
+ # @param [Plow::Generator] context A context reference to the generator controller. (i.e. Strategy pattern)
16
+ #
17
+ # @example
18
+ # class Plow
19
+ # class Generator
20
+ # def initialize
21
+ # @strategy = Plow::Strategy::UbuntuHardy::UserHomeWebApp.new(self)
22
+ # end
23
+ # end
24
+ # end
25
+ def initialize(context)
26
+ @context = context
27
+ @users_file_path = "/etc/passwd"
28
+ @vhost_file_name = "#{context.site_name}.conf"
29
+ @vhost_file_path = "/etc/apache2/sites-available/#{vhost_file_name}"
30
+
31
+ @vhost_template_file_path = "#{File.dirname(__FILE__)}/templates/apache2-vhost.conf"
32
+ end
33
+
34
+ ##
35
+ # Begins executing this strategy. In addition to the following exceptions, this method may
36
+ # also raise exceptions found in private methods of this class.
37
+ #
38
+ # @raise [Plow::AppRootAlreadyExistsError] Raised if the web-app root path directory
39
+ # aleady exists
40
+ # @raise [Plow::ConfigFileAlreadyExistsError] Raised if a apache2 vhost configuration file
41
+ # cannot be found
42
+ def execute
43
+ if user_exists?
44
+ say "existing #{context.user_name} user"
45
+ else
46
+ say "creating #{context.user_name} user"
47
+ create_user
48
+ end
49
+
50
+ if user_home_exists?
51
+ say "existing #{user_home_path}"
52
+ else
53
+ say "creating #{user_home_path}"
54
+ create_user_home
55
+ end
56
+
57
+ if sites_home_exists?
58
+ say "existing #{sites_home_path}"
59
+ else
60
+ say "creating #{sites_home_path}"
61
+ create_sites_home
62
+ end
63
+
64
+ if app_root_exists?
65
+ raise(Plow::AppRootAlreadyExistsError, app_root_path)
66
+ else
67
+ say "creating #{app_root_path}"
68
+ create_app_root
69
+ end
70
+
71
+ @app_public_path = "#{app_root_path}/public"
72
+ say "creating #{@app_public_path}"
73
+ create_app_public
74
+
75
+ @app_log_path = "#{app_root_path}/log"
76
+ say "creating #{app_log_path}"
77
+ create_app_logs
78
+
79
+ if vhost_config_exists?
80
+ raise(Plow::ConfigFileAlreadyExistsError, vhost_file_path)
81
+ else
82
+ say "creating #{vhost_file_path}"
83
+ create_vhost_config
84
+ end
85
+
86
+ say "installing #{vhost_file_path}"
87
+ install_vhost_config
88
+ end
89
+
90
+ ############################################################################################################
91
+
92
+ private
93
+
94
+ ##
95
+ # Proxy method to +Plow::Generator#say+
96
+ # @param [String] message A user output message
97
+ def say(message)
98
+ context.say(message)
99
+ end
100
+
101
+ ##
102
+ # Proxy method to +Plow::Generator#shell+
103
+ # @param [String] commands Shell commands with multi-line support.
104
+ def shell(commands)
105
+ context.shell(commands)
106
+ end
107
+
108
+ ##
109
+ # Reads the file at +users_file_path+ and yields each user iteratively.
110
+ #
111
+ #
112
+ # @yield [Hash] Each user account
113
+ # @example
114
+ # users do |user|
115
+ # user[:name] #=> [String] The name
116
+ # user[:password] #=> [String] The bogus password
117
+ # user[:id] #=> [Number] The uid number
118
+ # user[:group_ip] #=> [Number] The gid number
119
+ # user[:info] #=> [String] General account info
120
+ # user[:home_path] #=> [String] The path to the home directory
121
+ # user[:shell_path] #=> [String] The path to the default shell
122
+ # end
123
+ def users(&block)
124
+ File.readlines(users_file_path).each do |user_line|
125
+ user_line = user_line.chomp.split(':')
126
+ user = {
127
+ :name => user_line[0],
128
+ :password => user_line[1],
129
+ :id => user_line[2].to_i,
130
+ :group_id => user_line[3].to_i,
131
+ :info => user_line[4],
132
+ :home_path => user_line[5],
133
+ :shell_path => user_line[6]
134
+ }
135
+ yield user
136
+ end
137
+ end
138
+
139
+ ############################################################################################################
140
+
141
+ ##
142
+ # Determines if the context.user_name already exists or not
143
+ #
144
+ # @return [Boolean] +true+ if found otherwise +false+
145
+ # @raise [Plow::ReservedSystemUserNameError] Raised if the +context.user_name+ is a reserved
146
+ # system user name
147
+ def user_exists?
148
+ users do |user|
149
+ if user[:name] == context.user_name
150
+ unless user[:id] >= 1000 && user[:id] != 65534
151
+ raise(Plow::ReservedSystemUserNameError, context.user_name)
152
+ end
153
+ return true
154
+ end
155
+ end
156
+
157
+ return false
158
+ end
159
+
160
+ ##
161
+ # Creates a system user account for +context.user_name+
162
+ def create_user
163
+ shell "adduser #{context.user_name}"
164
+ end
165
+
166
+ ############################################################################################################
167
+
168
+ ##
169
+ # Determines if a home path for the +context.user_name+ already exists
170
+ #
171
+ # @return [Boolean] +true+ if the path already exists, otherwise +false+
172
+ # @raise [Plow::SystemUserNameNotFoundError] Raised if the +context.user_name+ is not found
173
+ # even after it has been created
174
+ def user_home_exists?
175
+ users do |user|
176
+ if user[:name] == context.user_name
177
+ @user_home_path = user[:home_path]
178
+ return Dir.exists?(user[:home_path])
179
+ end
180
+ end
181
+
182
+ raise(Plow::SystemUserNameNotFoundError, context.user_name)
183
+ end
184
+
185
+ ##
186
+ # Creates a +user_home_path+
187
+ def create_user_home
188
+ shell <<-RUN
189
+ mkdir #{user_home_path}
190
+ chown #{context.user_name}:#{context.user_name} #{user_home_path}
191
+ RUN
192
+ end
193
+
194
+ ############################################################################################################
195
+
196
+ ##
197
+ # Determines if the +sites_home_path+ already exists. As a side-effect, also correctly
198
+ # sets the +@sites_home_path+ variable.
199
+ # @return [Boolean] +true+ if the path already exists, otherwise +false+
200
+ def sites_home_exists?
201
+ @sites_home_path = "#{user_home_path}/sites"
202
+ Dir.exists?(sites_home_path)
203
+ end
204
+
205
+ ##
206
+ # Creates the +site_home_path+
207
+ def create_sites_home
208
+ shell <<-RUN
209
+ mkdir #{sites_home_path}
210
+ chown #{context.user_name}:#{context.user_name} #{sites_home_path}
211
+ RUN
212
+ end
213
+
214
+ ############################################################################################################
215
+
216
+ ##
217
+ # Determines if the +app_root_path+ already exists. As a side-effect, also correctly
218
+ # sets the +@app_root_path+ variable.
219
+ # @return [Boolean] +true+ if the path exists, otherwise +false+
220
+ def app_root_exists?
221
+ @app_root_path = "#{sites_home_path}/#{context.site_name}"
222
+ Dir.exists?(app_root_path)
223
+ end
224
+
225
+ ##
226
+ # Creates the +app_root_path+
227
+ def create_app_root
228
+ shell <<-RUN
229
+ mkdir #{app_root_path}
230
+ chown #{context.user_name}:#{context.user_name} #{app_root_path}
231
+ RUN
232
+ end
233
+
234
+ ############################################################################################################
235
+
236
+ ##
237
+ # Creates the app public structure at +app_public_path+
238
+ def create_app_public
239
+ shell <<-RUN
240
+ mkdir #{app_public_path}
241
+ touch #{app_public_path}/index.html
242
+ chown -R #{context.user_name}:#{context.user_name} #{app_public_path}
243
+ RUN
244
+ end
245
+
246
+ ############################################################################################################
247
+
248
+ ##
249
+ # Creates the app log structure at +app_log_path+
250
+ def create_app_logs
251
+ shell <<-RUN
252
+ mkdir #{app_log_path}
253
+ mkdir #{app_log_path}/apache2
254
+ chmod 750 #{app_log_path}/apache2
255
+
256
+ touch #{app_log_path}/apache2/access.log
257
+ touch #{app_log_path}/apache2/error.log
258
+
259
+ chmod 640 #{app_log_path}/apache2/*.log
260
+ chown -R #{context.user_name}:#{context.user_name} #{app_log_path}
261
+ chown root -R #{app_log_path}/apache2
262
+ RUN
263
+ end
264
+
265
+ ############################################################################################################
266
+
267
+ ##
268
+ # Determines if the apache2 vhost config file already exists
269
+ # @return [Boolean] +true+ if the file exists, otherwise +false+
270
+ def vhost_config_exists?
271
+ Dir.exists?(vhost_file_path)
272
+ end
273
+
274
+ ##
275
+ # Creates an apache2 vhost config file from a template file to a +vhost_file_path+
276
+ def create_vhost_config
277
+ File.open(vhost_file_path, 'wt') do |file|
278
+ template_context = {
279
+ :site_name => context.site_name,
280
+ :site_aliases => context.site_aliases,
281
+ :app_public_path => app_public_path,
282
+ :app_log_path => app_log_path
283
+ }
284
+
285
+ config = context.evaluate_template(vhost_template_file_path, template_context)
286
+ file.write(config)
287
+ end
288
+ end
289
+
290
+ ############################################################################################################
291
+
292
+ ##
293
+ # Installs the apache2 vhost config file by enabling the site and restarting the web server
294
+ def install_vhost_config
295
+ shell <<-RUN
296
+ a2ensite #{vhost_file_name}
297
+ apache2ctl graceful
298
+ RUN
299
+ end
300
+ end
301
+
302
+ end
303
+ end
304
+ end
data/lib/plow.rb ADDED
@@ -0,0 +1,18 @@
1
+ # encoding: UTF-8
2
+
3
+ unless RUBY_VERSION >= '1.9.1'
4
+ abort <<-ERROR
5
+ Incompatible ruby version error in #{__FILE__} near line #{__LINE__}
6
+ This library requires at least ruby v1.9.1 but you're using ruby v#{RUBY_VERSION}
7
+ Please see http://www.ruby-lang.org/
8
+ ERROR
9
+ end
10
+
11
+ require 'plow/core_ext/object'
12
+
13
+ require 'plow/errors'
14
+ require 'plow/application'
15
+
16
+ class Plow
17
+ VERSION = "0.1.0"
18
+ end
@@ -0,0 +1,27 @@
1
+ root:x:0:0:root:/root:/bin/bash
2
+ daemon:x:1:1:daemon:/usr/sbin:/bin/sh
3
+ bin:x:2:2:bin:/bin:/bin/sh
4
+ sys:x:3:3:sys:/dev:/bin/sh
5
+ sync:x:4:65534:sync:/bin:/bin/sync
6
+ games:x:5:60:games:/usr/games:/bin/sh
7
+ man:x:6:12:man:/var/cache/man:/bin/sh
8
+ lp:x:7:7:lp:/var/spool/lpd:/bin/sh
9
+ mail:x:8:8:mail:/var/mail:/bin/sh
10
+ news:x:9:9:news:/var/spool/news:/bin/sh
11
+ uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
12
+ proxy:x:13:13:proxy:/bin:/bin/sh
13
+ www-data:x:33:33:www-data:/var/www:/bin/sh
14
+ backup:x:34:34:backup:/var/backups:/bin/sh
15
+ list:x:38:38:Mailing List Manager:/var/list:/bin/sh
16
+ irc:x:39:39:ircd:/var/run/ircd:/bin/sh
17
+ gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
18
+ nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
19
+ libuuid:x:100:101::/var/lib/libuuid:/bin/sh
20
+ dhcp:x:101:102::/nonexistent:/bin/false
21
+ syslog:x:102:103::/home/syslog:/bin/false
22
+ klog:x:103:104::/home/klog:/bin/false
23
+ sshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin
24
+ Debian-exim:x:105:109::/var/spool/exim4:/bin/false
25
+ sadmin:x:1000:1000:,,,:/home/sadmin:/bin/bash
26
+ mysql:x:106:111:MySQL Server,,,:/var/lib/mysql:/bin/false
27
+ steve:x:1001:1001:,,,:/home/steve:/bin/bash
@@ -0,0 +1,3 @@
1
+ <VirtualHost *:80>
2
+ ServerName <%= @site_name %>
3
+ </VirtualHost>
@@ -0,0 +1,241 @@
1
+ # encoding: UTF-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
+
4
+ describe Plow::Application do
5
+
6
+ before(:each) do
7
+ @expected_version_stamp = "Plow v0.1.0. Copyright (c) 2009 Ryan Sobol. Licensed under the MIT license."
8
+ end
9
+
10
+ ##################################################################################################
11
+
12
+ describe ".version_stamp" do
13
+ it "should create a version stamp as a String" do
14
+ Plow::Application.send(:version_stamp).should == @expected_version_stamp
15
+ end
16
+ end
17
+
18
+ ##################################################################################################
19
+
20
+ describe ".launch when failing" do
21
+ before(:each) do
22
+ @expected_message = <<MESSAGE
23
+ Usage: plow USER_NAME SITE_NAME [SITE_ALIAS ...]
24
+
25
+ Arguments:
26
+ USER_NAME Name of a Linux system account user (e.g. steve)
27
+ SITE_NAME Name of the web-site (e.g. www.apple.com)
28
+ SITE_ALIAS (Optional) List of alias names of the web-site (e.g. apple.com)
29
+
30
+ Summary:
31
+ Plows the fertile soil of your filesystem into neatly organized plots of web-site templates
32
+
33
+ Description:
34
+ 1. Sharpens it's blade by ensuring that both a Linux system user account and it's home path exist
35
+ 2. Penetrates the soil by forming the web-site root path within the user home
36
+ 3. Seeds the web-site with an index page and web server log files
37
+ 4. Fertilizes the web-site by installing a virtual host configuration into the web server
38
+
39
+ Example:
40
+ plow steve www.apple.com apple.com
41
+ MESSAGE
42
+ $stdout = StringIO.new
43
+ $stderr = StringIO.new
44
+ end
45
+
46
+ after(:each) do
47
+ $stdout = STDOUT
48
+ $stderr = STDERR
49
+ end
50
+
51
+ it "should output the version stamp" do
52
+ lambda { Plow::Application.launch }.should raise_error
53
+ $stdout.string.should == @expected_version_stamp + "\n"
54
+ end
55
+
56
+ it "should abort with usage message with 0 arguments" do
57
+ lambda { Plow::Application.launch }.should raise_error(SystemExit, @expected_message)
58
+ end
59
+
60
+ it "should abort with usage message with 1 argument" do
61
+ lambda { Plow::Application.launch('marco') }.should raise_error(SystemExit, @expected_message)
62
+ end
63
+ end
64
+
65
+ ##################################################################################################
66
+
67
+ describe ".launch when passing" do
68
+ before(:each) do
69
+ $stdout = StringIO.new
70
+ end
71
+
72
+ after(:each) do
73
+ $stdout = STDOUT
74
+ end
75
+
76
+ it "should output the version stamp" do
77
+ argv = ['steve', 'www.apple.com']
78
+ generator = mock('generator')
79
+
80
+ Plow::Generator.should_receive(:new)
81
+ .with(*argv)
82
+ .and_return(generator)
83
+ generator.should_receive(:run!)
84
+
85
+ Plow::Application.launch(*argv)
86
+
87
+ $stdout.string.should == @expected_version_stamp + "\n"
88
+ end
89
+
90
+ it "should start the generator with 2 arguments" do
91
+ argv = ['steve', 'www.apple.com']
92
+ generator = mock('generator')
93
+
94
+ Plow::Generator.should_receive(:new)
95
+ .with(*argv)
96
+ .and_return(generator)
97
+ generator.should_receive(:run!)
98
+
99
+ Plow::Application.launch(*argv).should == 0
100
+ end
101
+
102
+ it "should start the generator with 3 arguments" do
103
+ argv = ['marco-polo', 'www.marcopolo.com', 'marcopolo.com']
104
+ generator = mock('generator')
105
+
106
+ Plow::Generator.should_receive(:new)
107
+ .with(*argv)
108
+ .and_return(generator)
109
+ generator.should_receive(:run!)
110
+
111
+ Plow::Application.launch(*argv).should == 0
112
+ end
113
+
114
+ it "should start the generator with 4 arguments" do
115
+ argv = ['marco-polo', 'www.marcopolo.com', 'marcopolo.com', 'asia.marcopolo.com']
116
+ generator = mock('generator')
117
+
118
+ Plow::Generator.should_receive(:new)
119
+ .with(*argv)
120
+ .and_return(generator)
121
+ generator.should_receive(:run!)
122
+
123
+ Plow::Application.launch(*argv).should == 0
124
+ end
125
+ end
126
+
127
+ ##################################################################################################
128
+
129
+ describe "when handling errors from Plow::Generator.new" do
130
+ before(:each) do
131
+ @bad_argv = ['bad user name', 'bad site name', 'bad site alias']
132
+ $stdout = StringIO.new
133
+ $stderr = StringIO.new
134
+ end
135
+
136
+ after(:each) do
137
+ $stdout = STDOUT
138
+ $stderr = STDERR
139
+ end
140
+
141
+ it "should render error message to the user for raised Plow::InvalidSystemUserNameError" do
142
+ expected_error = Plow::InvalidSystemUserNameError.new(@bad_argv[0])
143
+ Plow::Generator.should_receive(:new).and_raise(expected_error)
144
+
145
+ expected_message = "ERROR: #{@bad_argv[0]} is an invalid system user name"
146
+ lambda { Plow::Application.launch(*@bad_argv) }.should raise_error(SystemExit, expected_message)
147
+ end
148
+
149
+ it "should render error message to the user for raised Plow::InvalidWebSiteNameError" do
150
+ expected_error = Plow::InvalidWebSiteNameError.new(@bad_argv[1])
151
+ Plow::Generator.should_receive(:new).and_raise(expected_error)
152
+
153
+ expected_message = "ERROR: #{@bad_argv[1]} is an invalid web-site name"
154
+ lambda { Plow::Application.launch(*@bad_argv) }.should raise_error(SystemExit, expected_message)
155
+ end
156
+
157
+ it "should render error message to the user for raised Plow::InvalidWebSiteAliasError" do
158
+ expected_error = Plow::InvalidWebSiteAliasError.new(@bad_argv[2])
159
+ Plow::Generator.should_receive(:new).and_raise(expected_error)
160
+
161
+ expected_message = "ERROR: #{@bad_argv[2]} is an invalid web-site alias"
162
+ lambda { Plow::Application.launch(*@bad_argv) }.should raise_error(SystemExit, expected_message)
163
+ end
164
+ end
165
+
166
+ describe "when handing errors from Plow::Generator.run!" do
167
+ before(:each) do
168
+ $stdout = StringIO.new
169
+ $stderr = StringIO.new
170
+ @argv = ['steve', 'www.apple.com', 'apple.com']
171
+ @generator = mock('generator')
172
+ end
173
+
174
+ after(:each) do
175
+ $stdout = STDOUT
176
+ $stderr = STDERR
177
+ end
178
+
179
+ it "should render error message to the user for raised Plow::NonRootProcessOwnerError" do
180
+ expected_error = Plow::NonRootProcessOwnerError
181
+
182
+ Plow::Generator.should_receive(:new)
183
+ .with(*@argv)
184
+ .and_return(@generator)
185
+ @generator.should_receive(:run!).and_raise(expected_error)
186
+
187
+ expected_message = "ERROR: This process must be owned or executed by root"
188
+ lambda { Plow::Application.launch(*@argv) }.should raise_error(SystemExit, expected_message)
189
+ end
190
+
191
+ it "should render error message to the user for raised Plow::ReservedSystemUserNameError" do
192
+ expected_error = Plow::ReservedSystemUserNameError.new(@argv[0])
193
+
194
+ Plow::Generator.should_receive(:new)
195
+ .with(*@argv)
196
+ .and_return(@generator)
197
+ @generator.should_receive(:run!).and_raise(expected_error)
198
+
199
+ expected_message = "ERROR: #{@argv[0]} is a reserved system user name"
200
+ lambda { Plow::Application.launch(*@argv) }.should raise_error(SystemExit, expected_message)
201
+ end
202
+
203
+ it "should render error message to the user for raised Plow::SystemUserNameNotFoundError" do
204
+ expected_error = Plow::SystemUserNameNotFoundError.new(@argv[0])
205
+
206
+ Plow::Generator.should_receive(:new)
207
+ .with(*@argv)
208
+ .and_return(@generator)
209
+ @generator.should_receive(:run!).and_raise(expected_error)
210
+
211
+ expected_message = "ERROR: System user name #{@argv[0]} cannot be found when it should exist"
212
+ lambda { Plow::Application.launch(*@argv) }.should raise_error(SystemExit, expected_message)
213
+ end
214
+
215
+ it "should render error message to the user for raised Plow::AppRootAlreadyExistsError" do
216
+ app_home_path = "/home/#{@argv[0]}/sites/#{@argv[1]}"
217
+ expected_error = Plow::AppRootAlreadyExistsError.new(app_home_path)
218
+
219
+ Plow::Generator.should_receive(:new)
220
+ .with(*@argv)
221
+ .and_return(@generator)
222
+ @generator.should_receive(:run!).and_raise(expected_error)
223
+
224
+ expected_message = "ERROR: Application root path #{app_home_path} already exists"
225
+ lambda { Plow::Application.launch(*@argv) }.should raise_error(SystemExit, expected_message)
226
+ end
227
+
228
+ it "should render error message to the user for raised Plow::AppRootAlreadyExistsError" do
229
+ config_file_path = '/etc/apache2/sites_available/vhost.conf'
230
+ expected_error = Plow::ConfigFileAlreadyExistsError.new(config_file_path)
231
+
232
+ Plow::Generator.should_receive(:new)
233
+ .with(*@argv)
234
+ .and_return(@generator)
235
+ @generator.should_receive(:run!).and_raise(expected_error)
236
+
237
+ expected_message = "ERROR: Configuration file #{config_file_path} already exists"
238
+ lambda { Plow::Application.launch(*@argv) }.should raise_error(SystemExit, expected_message)
239
+ end
240
+ end
241
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
4
+
5
+ describe Plow::BindingStruct do
6
+
7
+ before(:each) do
8
+ @arguments = { first_name: 'Carl', last_name: 'Sagan' }
9
+ @struct = Plow::BindingStruct.new(@arguments)
10
+ end
11
+
12
+ ##################################################################################################
13
+
14
+ describe ".new" do
15
+ it "should create instance variables for all keys of a parameter Hash" do
16
+ @struct.instance_variables.sort.should == @arguments.keys.sort.map { |key| "@#{key}".to_sym }
17
+ end
18
+
19
+ it "should initialze all instance variables with the values of a parameter Hash" do
20
+ @struct.instance_variables.each do |ivar|
21
+ @struct.instance_variable_get(ivar).should == @arguments[ivar.to_s.gsub("@", '').to_sym]
22
+ end
23
+ end
24
+ end
25
+
26
+ ##################################################################################################
27
+
28
+ describe "\#get_binding" do
29
+ it "should return a Binding object of the instance" do
30
+ ivars = @arguments.keys.sort.map { |key| "@#{key}".to_sym }
31
+ ivars.each do |ivar|
32
+ actual = eval(ivar.to_s, @struct.get_binding)
33
+ actual.should == @arguments[ivar.to_s.gsub("@", '').to_sym]
34
+ actual.should == @struct.instance_variable_get(ivar)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: UTF-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
+
4
+ describe "Custom Application Errors" do
5
+ it "Plow::NonRootProcessOwnerError should be a kind of StandardError" do
6
+ Plow::NonRootProcessOwnerError.new.should be_a_kind_of(StandardError)
7
+ end
8
+
9
+ it "Plow::InvalidSystemUserNameError should be a kind of StandardError" do
10
+ Plow::InvalidSystemUserNameError.new.should be_a_kind_of(StandardError)
11
+ end
12
+
13
+ it "Plow::InvalidWebSiteNameError should be a kind of StandardError" do
14
+ Plow::InvalidWebSiteNameError.new.should be_a_kind_of(StandardError)
15
+ end
16
+
17
+ it "Plow::InvalidWebSiteAliasError should be a kind of StandardError" do
18
+ Plow::InvalidWebSiteAliasError.new.should be_a_kind_of(StandardError)
19
+ end
20
+
21
+ it "Plow::ReservedSystemUserNameError should be a kind of StandardError" do
22
+ Plow::ReservedSystemUserNameError.new.should be_a_kind_of(StandardError)
23
+ end
24
+
25
+ it "Plow::SystemUserNameNotFoundError should be a kind of StandardError" do
26
+ Plow::SystemUserNameNotFoundError.new.should be_a_kind_of(StandardError)
27
+ end
28
+
29
+ it "Plow::AppRootAlreadyExistsError should be a kind of StandardError" do
30
+ Plow::AppRootAlreadyExistsError.new.should be_a_kind_of(StandardError)
31
+ end
32
+
33
+ it "Plow::ConfigFileAlreadyExistsError should be a kind of StandardError" do
34
+ Plow::ConfigFileAlreadyExistsError.new.should be_a_kind_of(StandardError)
35
+ end
36
+ end