fail_fast 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/CHANGELOG.txt ADDED
@@ -0,0 +1,2 @@
1
+ 0.1.0
2
+ - initial version
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Alain Ravet
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,91 @@
1
+ # fail_fast : don't start your application if some preconditions are not met.
2
+
3
+ ## How to use :
4
+
5
+ Early in your project boot sequence insert code like
6
+
7
+ require 'fail_fast'
8
+ FailFast('database.yml').check do
9
+ has_active_record_db_for Rails.env
10
+ end
11
+
12
+ FailFast('database.mongo.yml').check do
13
+ has_mongoDB_for Rails.env
14
+ end
15
+
16
+ FailFast('path_to/config.yml', prefix=Rails.env).check do
17
+ has\_values_for 'author/fname', 'author/lname'
18
+ has\_url_for 'bug_tracker/url', :reachable => true
19
+ has\_email_for 'newsletter/to_address'
20
+
21
+ directory_exists_for '/tmp'
22
+ file_exists_for 'public/nda.pdf'
23
+ end
24
+
25
+
26
+ ## Info :
27
+
28
+ Failing fast is important.
29
+ This gem DSL lets you write tests scripts that run early in the boot sequence of an application.
30
+ An exception is raised if one or more tests fail, and you get a detailled report of all the problems encountered.
31
+
32
+ Some rules are based on the contents of configuration files (database.yml, config.yml, etc...) :
33
+
34
+ - can a database connnection be established?
35
+ - is the mongoDB server active?
36
+ - is there an _:application\_name_ value in _config.yml_, and does it match a regexp pattern?
37
+ - is the value of _:info\_email__ a valid email?
38
+ - is the value of _:sponspor\_link_ a valid url, and is the site up?
39
+
40
+ You can also add custom rules, not related to any config files :
41
+
42
+ - is there a _/tmp_, or an _public/upload_ directory on the server?
43
+ - can the server access _http://google.com_?
44
+ - is there a _public/nda\_pdf_ file?
45
+ - etc..
46
+
47
+
48
+ ## Features :
49
+
50
+ ### _free/direct_ commands (not linked to the yaml file contents) :
51
+
52
+ directory_exists '/tmp'
53
+ file_exists '/Users/me/.bash_profile'
54
+ has_mongoDB 'localhost', 'db_app_1'
55
+ has_active_record_db :host => 'dbserv', :adapter => 'mysql', :database => 'db'
56
+
57
+
58
+ ### _keyed_ commands (linked to a value found in a yaml file) :
59
+
60
+ ####Test values linked to a key :
61
+
62
+ *presence :*
63
+
64
+ has_value_for :application_name
65
+ has_values_for 'author/fname', 'author/lname'
66
+
67
+ *contents <-> a regexp or pattern :*
68
+
69
+ has_value_for 'level', /(alpha|beta|production)/
70
+ has_url_for 'bug_tracker/url'
71
+ has_email_for 'newsletter/to_address'
72
+
73
+ Test the file system :
74
+
75
+ directory_exists_for 'public/assets'
76
+ file_exists_for 'public/500_custom.html'
77
+
78
+ Test external services :
79
+
80
+ # is a webserver up ?
81
+ has_url_for 'bug_tracker/url', :reachable => true
82
+ has_url_for 'bug_tracker/url', :reachable => true, :may_add_trailing_slash => true
83
+
84
+
85
+ # can we connect to a mongoDB db/server :
86
+ has_mongoDB_for 'test/mongoDB'
87
+ has_mongoDB_for 'test/unknown_mongoDB_db', :check_database => false
88
+
89
+ # can we connect to a SQL db :
90
+ has_active_record_db_for 'production/db_connection'
91
+
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "fail_fast"
8
+ gem.summary = %Q{raises an error if the yaml contents of a config file does pass a test script.}
9
+ gem.description = %Q{raises an error if the yaml contents of a config file does not pass a test script.}
10
+ gem.email = "alainravet@gmail.com"
11
+ gem.homepage = "http://github.com/alainravet/fail_fast"
12
+ gem.authors = ["Alain Ravet"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.add_development_dependency "mongo"
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ require 'spec/rake/spectask'
23
+ Spec::Rake::SpecTask.new(:spec) do |spec|
24
+ spec.libs << 'lib' << 'spec'
25
+ spec.spec_files = FileList['spec/**/*_spec.rb']
26
+ end
27
+
28
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
29
+ spec.libs << 'lib' << 'spec'
30
+ spec.pattern = 'spec/**/*_spec.rb'
31
+ spec.rcov = true
32
+ end
33
+
34
+ task :spec => :check_dependencies
35
+
36
+ task :default => :spec
37
+
38
+ require 'rake/rdoctask'
39
+ Rake::RDocTask.new do |rdoc|
40
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
41
+
42
+ rdoc.rdoc_dir = 'rdoc'
43
+ rdoc.title = "config_file_check #{version}"
44
+ rdoc.rdoc_files.include('README*')
45
+ rdoc.rdoc_files.include('lib/**/*.rb')
46
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/fail_fast.gemspec ADDED
@@ -0,0 +1,86 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{fail_fast}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Alain Ravet"]
12
+ s.date = %q{2010-06-20}
13
+ s.description = %q{raises an error if the yaml contents of a config file does not pass a test script.}
14
+ s.email = %q{alainravet@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.markdown"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "CHANGELOG.txt",
23
+ "LICENSE",
24
+ "README.markdown",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "fail_fast.gemspec",
28
+ "lib/fail_fast.rb",
29
+ "lib/fail_fast/check_active_record_db.rb",
30
+ "lib/fail_fast/check_email.rb",
31
+ "lib/fail_fast/check_file_system.rb",
32
+ "lib/fail_fast/check_mongo_db.rb",
33
+ "lib/fail_fast/check_url.rb",
34
+ "lib/fail_fast/check_value.rb",
35
+ "lib/fail_fast/main.rb",
36
+ "lib/fail_fast/report.txt.erb",
37
+ "show_all_errors.rb",
38
+ "spec/file_is_empty_spec.rb",
39
+ "spec/file_is_missing_spec.rb",
40
+ "spec/file_system_spec.rb",
41
+ "spec/fixtures/empty.yml",
42
+ "spec/fixtures/simple.yml",
43
+ "spec/has_active_record_db_spec.rb",
44
+ "spec/has_email_for_spec.rb",
45
+ "spec/has_mongoDB_for_spec.rb",
46
+ "spec/has_url_for_spec.rb",
47
+ "spec/has_value_for_spec.rb",
48
+ "spec/how_to_use_spec.rb",
49
+ "spec/spec.opts",
50
+ "spec/spec_helper.rb"
51
+ ]
52
+ s.homepage = %q{http://github.com/alainravet/fail_fast}
53
+ s.rdoc_options = ["--charset=UTF-8"]
54
+ s.require_paths = ["lib"]
55
+ s.rubygems_version = %q{1.3.7}
56
+ s.summary = %q{raises an error if the yaml contents of a config file does pass a test script.}
57
+ s.test_files = [
58
+ "spec/file_is_empty_spec.rb",
59
+ "spec/file_is_missing_spec.rb",
60
+ "spec/file_system_spec.rb",
61
+ "spec/has_active_record_db_spec.rb",
62
+ "spec/has_email_for_spec.rb",
63
+ "spec/has_mongoDB_for_spec.rb",
64
+ "spec/has_url_for_spec.rb",
65
+ "spec/has_value_for_spec.rb",
66
+ "spec/how_to_use_spec.rb",
67
+ "spec/spec_helper.rb"
68
+ ]
69
+
70
+ if s.respond_to? :specification_version then
71
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
72
+ s.specification_version = 3
73
+
74
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
75
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
76
+ s.add_development_dependency(%q<mongo>, [">= 0"])
77
+ else
78
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
79
+ s.add_dependency(%q<mongo>, [">= 0"])
80
+ end
81
+ else
82
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
83
+ s.add_dependency(%q<mongo>, [">= 0"])
84
+ end
85
+ end
86
+
@@ -0,0 +1,107 @@
1
+ require 'active_record'
2
+ # ActiveRecord::Base.establish_connection(
3
+ # :adapter => "mysql",
4
+ # :host => "localhost",
5
+ # :username => "myuser",
6
+ # :password => "mypass",
7
+ # :database => "somedatabase"
8
+ # )
9
+ # ActiveRecord::Base.establish_connection(
10
+ # :adapter => "sqlite",
11
+ # :database => "path/to/dbfile"
12
+ # )
13
+ # ActiveRecord::Base.establish_connection(
14
+ # :adapter => "sqlite3",
15
+ # :dbfile => ":memory:"
16
+ #)
17
+
18
+ class FailFast
19
+ module CheckActiveRecordDB
20
+
21
+ # Ensure the ActiveRecord connection can be established :
22
+ #
23
+ # Usage :
24
+ # has_active_record_db :host => 'localhost', :adapter => 'sqlite3', :database=> 'prod_db'
25
+ #
26
+ def has_active_record_db(*params)
27
+ options = params.last.is_a?(Hash) ? params.pop : {}
28
+ begin
29
+ ActiveRecord::Base.establish_connection(options)
30
+ @connection = ActiveRecord::Base.connection
31
+ @success = @connection && @connection.active?
32
+ rescue => e
33
+ @success = false
34
+ @error_message = e.message
35
+ end
36
+ unless @success
37
+ FailFast.errors << ErrorDetails.new(nil, :active_record_db_connection_error, @error_message)
38
+ end
39
+ end
40
+
41
+ # Ensure the ActiveRecord connection can be established :
42
+ #
43
+ # Usage :
44
+ # has_active_record_db_for 'production/database'
45
+ #
46
+ def has_active_record_db_for(key, *params)
47
+ return unless has_value_for key
48
+ return unless has_value_for "#{key}/adapter"
49
+ return unless has_value_for "#{key}/database"
50
+
51
+ p = key_value_regexp_options(key, params)
52
+ key, options = p.key, p.options
53
+
54
+ begin
55
+ connection_options = p.value
56
+ ActiveRecord::Base.establish_connection(connection_options)
57
+ @connection = ActiveRecord::Base.connection
58
+ @success = @connection && @connection.active?
59
+ rescue => e
60
+ @success = false
61
+ @error_message = e.message
62
+ end
63
+ unless @success
64
+ FailFast.errors << ErrorDetails.new(key, :active_record_db_connection_error, @error_message)
65
+ end
66
+ end
67
+
68
+ end
69
+ end
70
+
71
+ FailFast.send :include, FailFast::CheckActiveRecordDB
72
+
73
+ __END__
74
+ # Ensure the mongoDB server can be reached, and the db could be opened :
75
+ #
76
+ # Usage :
77
+ # has_mongoDB_for 'test/mongoDB'
78
+ # has_mongoDB_for 'test/unknown_mongoDB_db', :check_database => false
79
+ #
80
+ def has_mongoDB_for(key, *params)
81
+ return unless has_value_for key
82
+ return unless has_value_for "#{key}/host"
83
+ return unless has_value_for "#{key}/database"
84
+
85
+ p = key_value_regexp_options(key, params)
86
+ key, options = p.key, p.options
87
+
88
+ value = value_for_deep_key(key)
89
+ host, port, db = value['host'], value['port'], value['database']
90
+
91
+ begin
92
+ @conn = Mongo::Connection.new(host, port)
93
+ rescue Mongo::ConnectionFailure
94
+ FailFast.errors << ErrorDetails.new(key, :mongoDB_server_not_found, host)
95
+ return
96
+ end
97
+
98
+ must_check_db = !(false == options[:check_database])
99
+ if must_check_db && !@conn.database_names.include?(db)
100
+ FailFast.errors << ErrorDetails.new(key, :mongoDB_db_not_found, db)
101
+ end
102
+ end
103
+
104
+ end
105
+ end
106
+
107
+
@@ -0,0 +1,34 @@
1
+ class FailFast
2
+
3
+ module CheckEmail
4
+ # Usage
5
+ # has_email_for 'test/admin_email'
6
+ #
7
+ def has_email_for(key, *params)
8
+ return unless has_value_for key
9
+
10
+ p = key_value_regexp_options(key, params)
11
+ key, options = p.key, p.options
12
+
13
+ value = value_for_deep_key(key)
14
+ if EmailValidator.invalid_email_address?(value)
15
+ FailFast.errors << ErrorDetails.new(key, :not_an_email, value)
16
+ end
17
+ end
18
+ end
19
+
20
+ module EmailValidator
21
+ VALID_EMAIL_ADDRESS_REGEXP = /^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/
22
+
23
+ def self.valid_email_address?(email)
24
+ email.strip!
25
+ !!(email =~ VALID_EMAIL_ADDRESS_REGEXP)
26
+ end
27
+
28
+ def self.invalid_email_address?(email)
29
+ !valid_email_address?(email)
30
+ end
31
+ end
32
+ end
33
+
34
+ FailFast.send :include, FailFast::CheckEmail
@@ -0,0 +1,65 @@
1
+ class FailFast
2
+ module CheckFileSystem
3
+
4
+ # Ensure the value is an existing directory
5
+ #
6
+ # Usage
7
+ # directory_exists '/tmp'
8
+ #
9
+ def directory_exists(path, *params)
10
+ unless File.exists?(path) && File.directory?(path)
11
+ FailFast.errors << ErrorDetails.new(nil, :directory_not_found, path)
12
+ end
13
+ end
14
+
15
+ # Ensure the value is an existing file
16
+ #
17
+ # Usage
18
+ # file_exists '~/.bash_profile'
19
+ #
20
+ def file_exists(path, *params)
21
+ unless File.exists?(path) && File.file?(path)
22
+ FailFast.errors << ErrorDetails.new(nil, :file_not_found, path)
23
+ end
24
+ end
25
+
26
+ # Ensure the key value is an existing directory
27
+ #
28
+ # Usage
29
+ # directory_exists_for 'foo/config'
30
+ #
31
+ def directory_exists_for(key, *params)
32
+ return unless has_value_for key
33
+
34
+ p = key_value_regexp_options(key, params)
35
+ key, options = p.key, p.options
36
+
37
+ path = value_for_deep_key(key)
38
+
39
+ unless File.exists?(path) && File.directory?(path)
40
+ FailFast.errors << ErrorDetails.new(key, :directory_not_found, p.value)
41
+ end
42
+ end
43
+
44
+ # Ensure the key value is an existing file exists
45
+ #
46
+ # Usage
47
+ # file_exists_for 'foo/config/app.yml'
48
+ #
49
+ def file_exists_for(key, *params)
50
+ return unless has_value_for key
51
+
52
+ p = key_value_regexp_options(key, params)
53
+ key, options = p.key, p.options
54
+
55
+ path = value_for_deep_key(key)
56
+
57
+ unless File.exists?(path) && File.file?(path)
58
+ FailFast.errors << ErrorDetails.new(key, :file_not_found, p.value)
59
+ end
60
+ end
61
+
62
+ end
63
+ end
64
+
65
+ FailFast.send :include, FailFast::CheckFileSystem
@@ -0,0 +1,61 @@
1
+ class FailFast
2
+ module CheckMongoDB
3
+
4
+ # Ensure the mongoDB server can be reached, and the db could be opened :
5
+ #
6
+ # Usage :
7
+ # has_mongoDB 'localhost'
8
+ # has_mongoDB 'localhost', 'my_db', :port => 1234, :timeout => 2
9
+ # has_mongoDB 'localhost', :port => 1234, :timeout => 2
10
+ #
11
+ def has_mongoDB(host, *params)
12
+ options = params.last.is_a?(Hash) ? params.pop : {}
13
+ db = params.first
14
+
15
+ begin
16
+ port = options.delete(:port)
17
+ @conn = Mongo::Connection.new(host, port, options)
18
+ rescue Mongo::ConnectionFailure
19
+ FailFast.errors << ErrorDetails.new(nil, :mongoDB_server_not_found, host)
20
+ return
21
+ end
22
+
23
+ if db && !@conn.database_names.include?(db)
24
+ FailFast.errors << ErrorDetails.new(nil, :mongoDB_db_not_found, db)
25
+ end
26
+ end
27
+
28
+ # Ensure the mongoDB server can be reached, and the db could be opened :
29
+ #
30
+ # Usage :
31
+ # has_mongoDB_for 'test/mongoDB'
32
+ # has_mongoDB_for 'test/unknown_mongoDB_db', :check_database => false
33
+ #
34
+ def has_mongoDB_for(key, *params)
35
+ return unless has_value_for key
36
+ return unless has_value_for "#{key}/host"
37
+ return unless has_value_for "#{key}/database"
38
+
39
+ p = key_value_regexp_options(key, params)
40
+ key, options = p.key, p.options
41
+
42
+ value = value_for_deep_key(key)
43
+ host, port, db = value['host'], value['port'], value['database']
44
+
45
+ begin
46
+ @conn = Mongo::Connection.new(host, port)
47
+ rescue Mongo::ConnectionFailure
48
+ FailFast.errors << ErrorDetails.new(key, :mongoDB_server_not_found, host)
49
+ return
50
+ end
51
+
52
+ must_check_db = !(false == options[:check_database])
53
+ if must_check_db && !@conn.database_names.include?(db)
54
+ FailFast.errors << ErrorDetails.new(key, :mongoDB_db_not_found, db)
55
+ end
56
+ end
57
+
58
+ end
59
+ end
60
+
61
+ FailFast.send :include, FailFast::CheckMongoDB
@@ -0,0 +1,73 @@
1
+ class FailFast
2
+
3
+ module CheckUrl
4
+ # Usage
5
+ # test if the url is valid :
6
+ # has_url_for 'test/server_url'
7
+ # test if the url is reachable :
8
+ # has_url_for 'test/server_url', :reachable => true
9
+ # test if the url is reachable, possibly after adding a trailing slash.
10
+ # (ex: http://example.com + http://example.com/)
11
+ # has_url_for 'test/server_url', :reachable => true, :may_add_trailing_slash => true
12
+ #
13
+ def has_url_for(key, *params)
14
+ return unless has_value_for key
15
+
16
+ p = key_value_regexp_options(key, params)
17
+ key, options = p.key, p.options
18
+
19
+ value = value_for_deep_key(key)
20
+ if UrlValidator.invalid_url?(value)
21
+ FailFast.errors << ErrorDetails.new(key, :not_a_url, value)
22
+ return
23
+ end
24
+ if true==options.delete(:reachable) && UrlValidator.unreachable_url?(value, options)
25
+ FailFast.errors << ErrorDetails.new(key, :url_not_reachable, value)
26
+ end
27
+ end
28
+ end
29
+
30
+ module UrlValidator
31
+ IPv4_PART = /\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]/ # 0-255
32
+ VALID_URL_REGEXP = %r{
33
+ \A
34
+ https?:// # http:// or https://
35
+ ([^\s:@]+:[^\s:@]*@)? # optional username:pw@
36
+ ( (([^\W_]+\.)*xn--)?[^\W_]+([-.][^\W_]+)*\.[a-z]{2,6}\.? | # domain (including Punycode/IDN)...
37
+ #{IPv4_PART}(\.#{IPv4_PART}){3} | # or IPv4
38
+ localhost ) # or localhost
39
+ (:\d{1,5})? # optional port
40
+ ([/?]\S*)? # optional /whatever or ?whatever
41
+ \Z
42
+ }iux
43
+
44
+ def self.valid_url?(url)
45
+ url.strip!
46
+ !!(url =~ VALID_URL_REGEXP)
47
+ end
48
+
49
+ def self.invalid_url?(url)
50
+ !valid_url?(url)
51
+ end
52
+
53
+ def self.reachable_url?(url_s, options = {:may_add_trailing_slash => false})
54
+ url_s = "http://#{url_s}" unless url_s =~ /http/
55
+ url = URI.parse(url_s)
56
+ http = Net::HTTP.new(url.host, url.port)
57
+ http.open_timeout = http.read_timeout = 5 #seconds
58
+ http.get(url.path)
59
+ true
60
+ rescue Exception
61
+ can_retry_after_appending_a_fwd_slash = (true == options[:may_add_trailing_slash]) && !(url_s =~ /\/$/)
62
+ can_retry_after_appending_a_fwd_slash ?
63
+ reachable_url?(url_s + '/', options) :
64
+ false
65
+ end
66
+
67
+ def self.unreachable_url?(url_s, options = {:may_add_trailing_slash => false})
68
+ !reachable_url?(url_s, options)
69
+ end
70
+ end
71
+ end
72
+
73
+ FailFast.send :include, FailFast::CheckUrl
@@ -0,0 +1,38 @@
1
+ class FailFast
2
+ module CheckValue
3
+
4
+ # Usage
5
+ # has_value_for 'str_key'
6
+ # has_value_for :sym_key, /localhost/
7
+ # returns
8
+ # true if succesful, false otherwise
9
+ def has_value_for(key, *params)
10
+ p = key_value_regexp_options(key, params)
11
+ key, options = p.key, p.options
12
+
13
+ nof_errors = FailFast.errors.size
14
+ if blank?(p.value)
15
+ FailFast.errors << ErrorDetails.new(key, :missing_value, nil)
16
+
17
+ elsif p.regexp
18
+ FailFast.errors << ErrorDetails.new(key, :value_does_not_match, p.value) unless p.value =~ p.regexp
19
+
20
+ elsif hash?(options) && range?(options[:in])
21
+ FailFast.errors << ErrorDetails.new(key, :value_not_in_range, p.value) unless options[:in].include?(p.value)
22
+
23
+ elsif hash?(options) && array?(options[:in])
24
+ FailFast.errors << ErrorDetails.new(key, :value_not_in_array, p.value) unless options[:in].include?(p.value)
25
+ end
26
+ no_new_error = nof_errors == FailFast.errors.size
27
+ end
28
+
29
+ # Usage
30
+ # has_values_for :sym_key, 'str_key'
31
+ #
32
+ def has_values_for(*keys)
33
+ keys.each{|key| has_value_for(key)}
34
+ end
35
+
36
+ end
37
+ end
38
+ FailFast.send :include, FailFast::CheckValue