fail_fast 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.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/CHANGELOG.txt +2 -0
- data/LICENSE +20 -0
- data/README.markdown +91 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/fail_fast.gemspec +86 -0
- data/lib/fail_fast/check_active_record_db.rb +107 -0
- data/lib/fail_fast/check_email.rb +34 -0
- data/lib/fail_fast/check_file_system.rb +65 -0
- data/lib/fail_fast/check_mongo_db.rb +61 -0
- data/lib/fail_fast/check_url.rb +73 -0
- data/lib/fail_fast/check_value.rb +38 -0
- data/lib/fail_fast/main.rb +89 -0
- data/lib/fail_fast/report.txt.erb +8 -0
- data/lib/fail_fast.rb +14 -0
- data/show_all_errors.rb +63 -0
- data/spec/file_is_empty_spec.rb +8 -0
- data/spec/file_is_missing_spec.rb +17 -0
- data/spec/file_system_spec.rb +40 -0
- data/spec/fixtures/empty.yml +0 -0
- data/spec/fixtures/simple.yml +32 -0
- data/spec/has_active_record_db_spec.rb +39 -0
- data/spec/has_email_for_spec.rb +13 -0
- data/spec/has_mongoDB_for_spec.rb +60 -0
- data/spec/has_url_for_spec.rb +22 -0
- data/spec/has_value_for_spec.rb +69 -0
- data/spec/how_to_use_spec.rb +45 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +86 -0
- metadata +136 -0
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
class FailFast
|
5
|
+
ERB_TEMPLATE = File.dirname(__FILE__) + '/report.txt.erb'
|
6
|
+
|
7
|
+
class Error < StandardError ; end
|
8
|
+
class ErrorDetails < Struct.new(:key, :kind, :value) ;
|
9
|
+
def has_key_and_kind?(akey, akind)
|
10
|
+
(key.to_s == akey.to_s) && kind.to_sym == akind.to_sym
|
11
|
+
end
|
12
|
+
def has_value_and_kind?(avalue, akind)
|
13
|
+
(value.to_s == avalue.to_s) && kind.to_sym == akind.to_sym
|
14
|
+
end
|
15
|
+
end
|
16
|
+
class Params < Struct.new(:key, :value, :regexp, :options) ; end
|
17
|
+
|
18
|
+
def initialize(path, prefix=nil)
|
19
|
+
@path = path
|
20
|
+
@prefix = prefix
|
21
|
+
@@errors = []
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.errors
|
25
|
+
@@errors
|
26
|
+
end
|
27
|
+
|
28
|
+
def check(&block)
|
29
|
+
if missing_file?(@path)
|
30
|
+
FailFast.errors << ErrorDetails.new(nil, :config_file_not_found, @path)
|
31
|
+
else
|
32
|
+
@hash = YAML.load(ERB.new(File.read(@path)).result) || {}
|
33
|
+
self.instance_eval(&block)
|
34
|
+
end
|
35
|
+
raise_and_print_errors if errors?
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def blank?( value) value.nil? || value.is_a?(String) && ''==value.strip end
|
42
|
+
def range?( value) value.is_a?(Range ) end
|
43
|
+
def regexp?(value) value.is_a?(Regexp) end
|
44
|
+
def array?( value) value.is_a?(Array ) end
|
45
|
+
def hash?( value) value.is_a?(Hash) end
|
46
|
+
def missing_file?(path) !File.exist?(path) end
|
47
|
+
|
48
|
+
# Usage
|
49
|
+
# value_for_deep_key('one/two/three')
|
50
|
+
# returns
|
51
|
+
# @hash[:one][:two][:three]
|
52
|
+
#
|
53
|
+
def value_for_deep_key(key)
|
54
|
+
key.to_s.split('/').inject(@hash) { |h, k| h[k] } rescue nil
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
def key_value_regexp_options(key, params)
|
59
|
+
last = params.pop
|
60
|
+
if last.is_a?(Hash)
|
61
|
+
options = last
|
62
|
+
else
|
63
|
+
params << last
|
64
|
+
options = {}
|
65
|
+
end
|
66
|
+
|
67
|
+
last = params.pop
|
68
|
+
if last.is_a?(Regexp)
|
69
|
+
regexp = last
|
70
|
+
else
|
71
|
+
params << last
|
72
|
+
end
|
73
|
+
|
74
|
+
key = "#{@prefix}/#{key}" if @prefix
|
75
|
+
value = value_for_deep_key(key)
|
76
|
+
|
77
|
+
Params.new(key, value, regexp, options)
|
78
|
+
end
|
79
|
+
|
80
|
+
def errors?
|
81
|
+
!FailFast.errors.empty?
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
def raise_and_print_errors
|
86
|
+
@errors = @@errors
|
87
|
+
raise "\n\n\n" + ERB.new(File.read(ERB_TEMPLATE)).result(binding) + "\n\n"
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
+------------------------------------------------------------------------------------------
|
2
|
+
| FAIL_FAST error : <%= @path.inspect %>
|
3
|
+
| key prefix = <%= @prefix.inspect %>
|
4
|
+
+------------------------------------------------------------------------------------------
|
5
|
+
| error key value
|
6
|
+
+------------------------------------------------------------------------------------------<% @errors.each do |e| %>
|
7
|
+
| * <%= "%-38s %-35s %-30s " % [ e.kind, e.key, e.value] %><% end %>
|
8
|
+
+------------------------------------------------------------------------------------------
|
data/lib/fail_fast.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'fail_fast/main'
|
2
|
+
|
3
|
+
require 'fail_fast/check_value'
|
4
|
+
require 'fail_fast/check_file_system'
|
5
|
+
require 'fail_fast/check_mongo_db'
|
6
|
+
require 'fail_fast/check_active_record_db'
|
7
|
+
require 'fail_fast/check_url'
|
8
|
+
require 'fail_fast/check_email'
|
9
|
+
|
10
|
+
|
11
|
+
def FailFast(path, prefix=nil)
|
12
|
+
FailFast.new(path, prefix)
|
13
|
+
end
|
14
|
+
|
data/show_all_errors.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'mongo'
|
3
|
+
|
4
|
+
def fake_http_server
|
5
|
+
require 'fakeweb'
|
6
|
+
FakeWeb.register_uri(:get, "http://example.com/index.html", :body => "I'm reachable!")
|
7
|
+
FakeWeb.register_uri(:get, "http://localhost/index.html", :body => "I'm reachable!")
|
8
|
+
FakeWeb.register_uri(:get, "http://example.com", :body => "I'm reachable!")
|
9
|
+
end
|
10
|
+
def fake_mongo_server_absent
|
11
|
+
require 'mocha'
|
12
|
+
Mongo::Connection.stubs(:new).raises(Mongo::ConnectionFailure)
|
13
|
+
end
|
14
|
+
def fake_mongo_db_absent
|
15
|
+
require 'mocha'
|
16
|
+
Mocha::Mockery.instance.stubba.unstub_all
|
17
|
+
|
18
|
+
conn = Mongo::Connection.new
|
19
|
+
conn.stubs(:database_names).returns []
|
20
|
+
Mongo::Connection.stubs(:new).returns(conn)
|
21
|
+
end
|
22
|
+
|
23
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__)+'/lib')
|
24
|
+
SPEC_DIR = File.dirname(__FILE__)+'/spec'
|
25
|
+
|
26
|
+
require 'fail_fast'
|
27
|
+
FailFast(SPEC_DIR + '/fixtures/simple.yml').check do
|
28
|
+
|
29
|
+
#test values :
|
30
|
+
has_value_for :first_keyNOT # single absent key
|
31
|
+
has_values_for :last_keyNOT, 'number_sixNOT' # multiple absent keys
|
32
|
+
has_value_for 'testNOT/mongoDB/database' # invalid yaml path
|
33
|
+
|
34
|
+
has_value_for :last_key, /(will_never_match)/ # value does not match regexp
|
35
|
+
|
36
|
+
has_email_for 'test/host' # value is not an email address
|
37
|
+
|
38
|
+
fake_http_server
|
39
|
+
has_url_for 'test/host' # value is not a url
|
40
|
+
|
41
|
+
#test http server :
|
42
|
+
has_url_for 'test/url_not_reachable', :reachable => true #server is not reachable
|
43
|
+
|
44
|
+
#test file system :
|
45
|
+
directory_exists '/foobarbaz' # not a directory
|
46
|
+
directory_exists_for 'test/a_file' # not a directory
|
47
|
+
|
48
|
+
file_exists '/tmp/foo/bar/??nOTaFile' # not a file
|
49
|
+
file_exists_for 'test/a_directory' # not a file
|
50
|
+
|
51
|
+
#test mondoDB
|
52
|
+
fake_mongo_server_absent
|
53
|
+
has_mongoDB '10.0.0.123', :timeout => 1 # no mongo server at this address
|
54
|
+
has_mongoDB_for 'test/mongoDB' # " " " " " " ""
|
55
|
+
|
56
|
+
fake_mongo_db_absent
|
57
|
+
has_mongoDB 'localhost', 'not_a_known_db'
|
58
|
+
has_mongoDB_for 'test/unknown_mongoDB_db' # a mongoDB, but the DB is unknown
|
59
|
+
|
60
|
+
#test ActiveRecord
|
61
|
+
has_active_record_db :host => 'localhost', :adapter => 'mysql', :database=> 'some-db'
|
62
|
+
has_active_record_db_for 'db_connection'
|
63
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "ConfigCheck on an empty file" do
|
4
|
+
it_should_not_raise_an_error("when there are no checks") { }
|
5
|
+
it_should_raise_an_error('anykey', :missing_value, 'when there is a has_value_for check') {
|
6
|
+
has_value_for :anykey
|
7
|
+
}
|
8
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "ConfigCheck on an unknown file" do
|
4
|
+
|
5
|
+
it "should not raise an error in new()" do
|
6
|
+
FailFast(UNKNOWN_FILE_PATH)
|
7
|
+
fail unless FailFast.errors.empty?
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should raise an error in fail_fast()" do
|
11
|
+
lambda {
|
12
|
+
FailFast(UNKNOWN_FILE_PATH).check do end
|
13
|
+
}.should raise_error
|
14
|
+
fail unless FailFast.errors.collect(&:kind) == [:config_file_not_found]
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
a_dir = SPEC_DIR + '/fixtures'
|
4
|
+
a_file = SPEC_DIR + '/fixtures/simple.yml'
|
5
|
+
|
6
|
+
|
7
|
+
describe 'directory_exists' do
|
8
|
+
context '' do
|
9
|
+
it_should_not_raise_an_error('when the directory exists' ) { directory_exists a_dir }
|
10
|
+
|
11
|
+
it_should_raise_a_direct_error('XYZ', :directory_not_found, 'when the directory does not exist' ) { directory_exists 'XYZ' }
|
12
|
+
it_should_raise_a_direct_error(a_file, :directory_not_found, 'when the path points to a File' ) { directory_exists a_file}
|
13
|
+
end
|
14
|
+
|
15
|
+
context '_for' do
|
16
|
+
it_should_not_raise_an_error('when the directory exists' ) { directory_exists_for 'test/a_directory' }
|
17
|
+
|
18
|
+
it_should_raise_an_error('test/a_file', :directory_not_found, 'when the path points to a File' ) { directory_exists_for 'test/a_file' }
|
19
|
+
it_should_raise_an_error('test/email', :directory_not_found, 'when the directory does not exist' ) { directory_exists_for 'test/email' }
|
20
|
+
it_should_raise_an_error('not_a_valid_key',:missing_value, 'when the key is invalid' ) { directory_exists_for 'not_a_valid_key' }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
describe 'file_exists' do
|
26
|
+
context '' do
|
27
|
+
it_should_not_raise_an_error('when the file exists' ) { file_exists a_file}
|
28
|
+
|
29
|
+
it_should_raise_a_direct_error('XYZ', :file_not_found, 'when the file does not exist' ) { file_exists 'XYZ' }
|
30
|
+
it_should_raise_a_direct_error(a_dir, :file_not_found, 'when the path points to a dir' ) { file_exists a_dir }
|
31
|
+
end
|
32
|
+
|
33
|
+
context '_for' do
|
34
|
+
it_should_not_raise_an_error('when the file exists' ) { file_exists_for 'test/a_file' }
|
35
|
+
|
36
|
+
it_should_raise_an_error('test/a_directory', :file_not_found, 'when the path points to a dir' ) { file_exists_for 'test/a_directory' }
|
37
|
+
it_should_raise_an_error('test/email', :file_not_found, 'when the file does not exist' ) { file_exists_for 'test/email' }
|
38
|
+
it_should_raise_an_error('not_a_valid_key', :missing_value, 'when the key is invalid' ) { file_exists_for 'not_a_valid_key' }
|
39
|
+
end
|
40
|
+
end
|
File without changes
|
@@ -0,0 +1,32 @@
|
|
1
|
+
first_key: premier
|
2
|
+
key_with_blank_value: <%= '' %>
|
3
|
+
last_key: dernier
|
4
|
+
test:
|
5
|
+
host: localhost
|
6
|
+
url: http://example.com/index.html
|
7
|
+
url_localhost: http://localhost/index.html
|
8
|
+
email: test@example.com
|
9
|
+
url_reachable: http://example.com
|
10
|
+
url_not_reachable: http://xxx.zzz
|
11
|
+
mongoDB:
|
12
|
+
host: localhost
|
13
|
+
database: sample_mongoDB
|
14
|
+
|
15
|
+
unreachable_mongoDB_server:
|
16
|
+
host: unreachable_host
|
17
|
+
database: "vasco-dpplus-auditlog-dev"
|
18
|
+
|
19
|
+
unknown_mongoDB_db:
|
20
|
+
host: localhost
|
21
|
+
database: unknown_mongoDB_db
|
22
|
+
|
23
|
+
a_directory: <%= SPEC_DIR + '/fixtures' %>
|
24
|
+
|
25
|
+
a_file: <%= SPEC_DIR + '/fixtures/simple.yml' %>
|
26
|
+
|
27
|
+
db_connection:
|
28
|
+
adapter: mysql
|
29
|
+
database: a_db
|
30
|
+
|
31
|
+
number_six: 6
|
32
|
+
letter_x: x
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe 'has_ar_db' do
|
4
|
+
context '' do
|
5
|
+
it_should_not_raise_an_error('when the connections succeeds' ) {
|
6
|
+
conn = Object.new ; conn.should_receive(:active?).and_return(true)
|
7
|
+
ActiveRecord::Base.should_receive(:connection).and_return(conn)
|
8
|
+
|
9
|
+
has_active_record_db :host => 'localhost', :adapter => 'mysql', :database=> 'a-db', :username => 'root'
|
10
|
+
}
|
11
|
+
|
12
|
+
it_should_raise_a_direct_error('ze-error-message', :active_record_db_connection_error, 'when the connection fails' ) {
|
13
|
+
exception = StandardError.new('ze-error-message')
|
14
|
+
ActiveRecord::Base.should_receive(:establish_connection).and_raise(exception)
|
15
|
+
|
16
|
+
has_active_record_db valid_connection_options = {}
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
context '_for' do
|
21
|
+
it_should_not_raise_an_error('when the connections succeeds' ) {
|
22
|
+
conn = Object.new ; conn.should_receive(:active?).and_return(true)
|
23
|
+
ActiveRecord::Base.should_receive(:connection).and_return(conn)
|
24
|
+
|
25
|
+
has_active_record_db_for 'db_connection'
|
26
|
+
}
|
27
|
+
|
28
|
+
it_should_raise_an_error('db_connection', :active_record_db_connection_error, 'when the connection fails' ) {
|
29
|
+
exception = StandardError.new('an-error-message')
|
30
|
+
ActiveRecord::Base.should_receive(:establish_connection).and_raise(exception)
|
31
|
+
|
32
|
+
has_active_record_db_for 'db_connection'
|
33
|
+
}
|
34
|
+
|
35
|
+
it_should_raise_an_error('invalid_key', :missing_value, 'when the key is invalid' ) {
|
36
|
+
has_active_record_db_for 'invalid_key'
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe 'has_email_for()' do
|
4
|
+
it_should_not_raise_an_error('when the value is an email') {
|
5
|
+
has_email_for 'test/email'
|
6
|
+
}
|
7
|
+
it_should_raise_an_error('test/url', :not_an_email, 'when the value is not an email') {
|
8
|
+
has_email_for 'test/url'
|
9
|
+
}
|
10
|
+
it_should_raise_an_error('invalid_key', :missing_value, 'when the key is invalid') {
|
11
|
+
has_email_for 'invalid_key'
|
12
|
+
}
|
13
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe 'has_mongoDB' do
|
4
|
+
|
5
|
+
context '' do
|
6
|
+
context 'when the mongo server cannot be reached' do
|
7
|
+
before(:each) { Mongo::Connection.should_receive(:new).any_number_of_times.and_raise(Mongo::ConnectionFailure) }
|
8
|
+
|
9
|
+
it_should_raise_a_direct_error('localhost', :mongoDB_server_not_found, 'when the mongoDB server connection failed') {
|
10
|
+
has_mongoDB 'localhost'
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when the mongo server can be reached' do
|
15
|
+
before(:each) do
|
16
|
+
conn = Mongo::Connection.new
|
17
|
+
conn.should_receive(:database_names).any_number_of_times.and_return %w(sample_mongoDB)
|
18
|
+
Mongo::Connection.should_receive(:new).and_return(conn)
|
19
|
+
end
|
20
|
+
|
21
|
+
it_should_not_raise_an_error('when the mongoDB server responds' ) { has_mongoDB 'localhost' }
|
22
|
+
it_should_not_raise_an_error('when the mongoDB server responds and the db can be found' ) { has_mongoDB 'localhost', 'sample_mongoDB' }
|
23
|
+
|
24
|
+
it_should_raise_a_direct_error('not_a_known_db', :mongoDB_db_not_found, 'when the database cannot be found on the mongoDB') {
|
25
|
+
has_mongoDB 'localhost', 'not_a_known_db'
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context '_for' do
|
31
|
+
context 'when the mongo server cannot be reached' do
|
32
|
+
before(:each) { Mongo::Connection.should_receive(:new).any_number_of_times.and_raise(Mongo::ConnectionFailure) }
|
33
|
+
|
34
|
+
it_should_raise_an_error('test/unreachable_mongoDB_server', :mongoDB_server_not_found, 'when the mongoDB server connection failed') {
|
35
|
+
has_mongoDB_for 'test/unreachable_mongoDB_server'
|
36
|
+
}
|
37
|
+
it_should_raise_an_error('not_a_valid_key', :missing_value, 'when the key is invalid') { has_mongoDB_for 'not_a_valid_key' }
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when the mongo server can be reached' do
|
41
|
+
before(:each) do
|
42
|
+
conn = Mongo::Connection.new
|
43
|
+
conn.should_receive(:database_names).any_number_of_times.and_return %w(sample_mongoDB)
|
44
|
+
Mongo::Connection.should_receive(:new).and_return(conn)
|
45
|
+
end
|
46
|
+
|
47
|
+
it_should_not_raise_an_error('when the mongoDB server responds and the database can be found') {
|
48
|
+
has_mongoDB_for 'test/mongoDB'
|
49
|
+
}
|
50
|
+
|
51
|
+
it_should_raise_an_error('test/unknown_mongoDB_db', :mongoDB_db_not_found,'when the database cannot be found on the mongoDB') {
|
52
|
+
has_mongoDB_for 'test/unknown_mongoDB_db'
|
53
|
+
}
|
54
|
+
|
55
|
+
it_should_not_raise_an_error('when :ignore_database => false desactivate the db check') {
|
56
|
+
has_mongoDB_for 'test/unknown_mongoDB_db', :check_database => false
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe 'has_url_for()' do
|
4
|
+
before(:all) do
|
5
|
+
FakeWeb.register_uri(:get, "http://example.com/index.html", :body => "I'm reachable!")
|
6
|
+
FakeWeb.register_uri(:get, "http://localhost/index.html" , :body => "I'm reachable!")
|
7
|
+
FakeWeb.register_uri(:get, "http://example.com" , :body => "I'm reachable!")
|
8
|
+
end
|
9
|
+
|
10
|
+
it_should_not_raise_an_error('when the value is an url') { has_url_for 'test/url' }
|
11
|
+
it_should_not_raise_an_error("when the domain is 'localhost'") { has_url_for 'test/url_localhost' }
|
12
|
+
it_should_raise_an_error('test/email', :not_a_url, 'when the value is not an url') { has_url_for 'test/email' }
|
13
|
+
|
14
|
+
it_should_raise_an_error('not_a_valid_key', :missing_value ,'when the value is blank or absent') { has_url_for 'not_a_valid_key' }
|
15
|
+
|
16
|
+
it_should_not_raise_an_error('when the url is reachable') {
|
17
|
+
has_url_for 'test/url_reachable' , :reachable => true, :may_add_trailing_slash => true
|
18
|
+
}
|
19
|
+
it_should_raise_an_error('test/url_not_reachable', :url_not_reachable ,'when the url is not reachable') {
|
20
|
+
has_url_for 'test/url_not_reachable', :reachable => true
|
21
|
+
}
|
22
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe 'has_value_for()' do
|
4
|
+
|
5
|
+
context 'when the value is present' do
|
6
|
+
it_should_not_raise_an_error('when the (string) key has a value') { has_value_for 'first_key' }
|
7
|
+
it_should_not_raise_an_error('when the (symbol) key has a value') { has_value_for :last_key }
|
8
|
+
it_should_not_raise_an_error('when all the keys have a value' ) { has_values_for 'first_key', :last_key }
|
9
|
+
it_should_not_raise_an_error('when the key is composed' ) { has_value_for 'test/mongoDB/host', /localhost/ }
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when the key is blank or absent' do
|
13
|
+
it_should_raise_an_error('key_not_present', :missing_value, 'when the key is absent') {
|
14
|
+
has_value_for :key_not_present
|
15
|
+
}
|
16
|
+
it_should_raise_an_error('key_with_blank_value', :missing_value, 'when the key has a blank value') {
|
17
|
+
has_values_for 'first_key', :key_with_blank_value
|
18
|
+
}
|
19
|
+
it_should_raise_an_error('key_with_blank_value', :missing_value, 'when one of the keys is absent') {
|
20
|
+
has_values_for :first_key, :key_with_blank_value
|
21
|
+
}
|
22
|
+
context 'because the key path is invalid' do
|
23
|
+
it_should_raise_an_error('INVALID/mongoDB/host', :missing_value, 'when the key path is invalid') {
|
24
|
+
has_value_for 'INVALID/mongoDB/host'
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when the value should match a regexp' do
|
30
|
+
it_should_not_raise_an_error('when the value matches a regexp') { has_value_for 'test/host', /localhost/ }
|
31
|
+
it_should_raise_an_error('letter_x', :value_does_not_match, 'when the value matches a regexp') {
|
32
|
+
has_value_for :letter_x, /localhost/
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when the value must be in a range' do
|
37
|
+
it_should_not_raise_an_error("when the value is in range ('a'..'z')") { has_value_for :letter_x, :in => ('a'..'z') }
|
38
|
+
it_should_raise_an_error('letter_x', :value_not_in_range, 'when the value is not in range (5..6)') {
|
39
|
+
has_value_for :letter_x, :in => (5..6)
|
40
|
+
}
|
41
|
+
it_should_raise_an_error('letter_x', :value_not_in_range, 'when the value is not in range (5..6)') {
|
42
|
+
has_value_for :letter_x, :in => (5..6)
|
43
|
+
}
|
44
|
+
it_should_not_raise_an_error('when the value is in range (5..6)' ) { has_value_for :number_six, :in => (5..6) }
|
45
|
+
it_should_raise_an_error('number_six', :value_not_in_range, 'when the value is not in range (5..6)') {
|
46
|
+
has_value_for :number_six, :in => ('a'..'z')
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when the value must be in an array' do
|
51
|
+
it_should_not_raise_an_error('when the value is in array [6, "x"]') {
|
52
|
+
has_value_for :letter_x, :in => [6, "x"]
|
53
|
+
has_value_for :number_six, :in => [6, "x"]
|
54
|
+
}
|
55
|
+
it_should_raise_an_error('letter_x', :value_not_in_array, 'when the value is not in array [0, 1]') {
|
56
|
+
has_value_for :letter_x, :in => [0, 1]
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'when a prefix is specified' do
|
61
|
+
it "should not raise an error when a prefix is used" do
|
62
|
+
lambda {
|
63
|
+
FailFast(SIMPLE_FILE_PATH, 'test').check do
|
64
|
+
has_value_for 'mongoDB/host', /localhost/
|
65
|
+
end
|
66
|
+
}.should_not raise_error
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "typical usage" do
|
4
|
+
|
5
|
+
example 'simple usage (short notation)' do
|
6
|
+
FailFast(SIMPLE_FILE_PATH).check do
|
7
|
+
has_value_for :first_key
|
8
|
+
has_values_for :last_key, 'number_six', :letter_x
|
9
|
+
has_value_for 'test/mongoDB/database' # composed key
|
10
|
+
|
11
|
+
|
12
|
+
has_value_for :last_key, /(premier|dernier)/ # regexp match
|
13
|
+
|
14
|
+
has_url_for 'test/url'
|
15
|
+
has_url_for 'test/url_reachable', :reachable => true, :may_add_trailing_slash => true
|
16
|
+
|
17
|
+
has_email_for 'test/email'
|
18
|
+
|
19
|
+
has_mongoDB_for 'test/mongoDB'
|
20
|
+
has_mongoDB_for 'test/unknown_mongoDB_db', :check_database => false
|
21
|
+
|
22
|
+
directory_exists_for 'test/a_directory'
|
23
|
+
file_exists_for 'test/a_file'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
example 'with a keys yaml prefix' do
|
28
|
+
rails_env_prefix = 'test' # == Rails.env
|
29
|
+
FailFast(SIMPLE_FILE_PATH, rails_env_prefix).check do
|
30
|
+
has_value_for 'mongoDB/database' # composed key
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
before(:each) { fake_the_remote_services() }
|
35
|
+
end
|
36
|
+
|
37
|
+
def fake_the_remote_services
|
38
|
+
FakeWeb.register_uri(:get, "http://example.com/index.html", :body => "I'm reachable!")
|
39
|
+
FakeWeb.register_uri(:get, "http://localhost/index.html", :body => "I'm reachable!")
|
40
|
+
FakeWeb.register_uri(:get, "http://example.com", :body => "I'm reachable!")
|
41
|
+
|
42
|
+
conn = Mongo::Connection.new
|
43
|
+
conn.should_receive(:database_names).any_number_of_times.and_return %w(sample_mongoDB)
|
44
|
+
Mongo::Connection.should_receive(:new).any_number_of_times.and_return(conn)
|
45
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'fail_fast'
|
2
|
+
require 'spec'
|
3
|
+
require 'spec/autorun'
|
4
|
+
require 'fakeweb'
|
5
|
+
require 'mongo'
|
6
|
+
|
7
|
+
SPEC_DIR = File.dirname(File.expand_path(__FILE__))
|
8
|
+
UNKNOWN_FILE_PATH = 'an_unknown_file_path'
|
9
|
+
EMPTY_FILE_PATH = File.expand_path(File.dirname(__FILE__) + '/fixtures/empty.yml')
|
10
|
+
SIMPLE_FILE_PATH = File.expand_path(File.dirname(__FILE__) + '/fixtures/simple.yml')
|
11
|
+
|
12
|
+
|
13
|
+
module DSLMacros
|
14
|
+
module ClassMethods
|
15
|
+
def it_should_not_raise_an_error(msg, &block)
|
16
|
+
it "should not raise an error #{msg}" do
|
17
|
+
begin
|
18
|
+
FailFast(SIMPLE_FILE_PATH).check do
|
19
|
+
raise "BUG : @@errorz should be empty \n#{FailFast.errors.inspect}" unless FailFast.errors.empty?
|
20
|
+
self.instance_eval(&block)
|
21
|
+
end
|
22
|
+
rescue => e
|
23
|
+
raise e
|
24
|
+
ensure
|
25
|
+
if 1 <= FailFast.errors.length
|
26
|
+
fail "ZZshould not have raised an error, but it raised\n#{FailFast.errors.join("\n")}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def it_should_raise_an_error(key, kind, msg, &block)
|
34
|
+
it "should raise an error #{kind}-#{key}-#{msg}" do
|
35
|
+
begin
|
36
|
+
FailFast(SIMPLE_FILE_PATH).check do
|
37
|
+
raise "BUG : @@errorz should be empty \n#{FailFast.errors.inspect}" unless FailFast.errors.empty?
|
38
|
+
self.instance_eval(&block)
|
39
|
+
end
|
40
|
+
rescue => e
|
41
|
+
# uncomment the next line after the refactoring/once error are no longer raise
|
42
|
+
# raise e
|
43
|
+
ensure
|
44
|
+
if FailFast.errors.empty?
|
45
|
+
fail "\ne2d\nshould have raised a #{kind} error for #{key} \n==#{e}"
|
46
|
+
elsif FailFast.errors.length == 1 && !FailFast.errors.first.has_key_and_kind?(key, kind)
|
47
|
+
fail "\ne2e\nshould have raised a #{kind.inspect} error for #{key.inspect}, but raised instead #{FailFast.errors.inspect}"
|
48
|
+
elsif 2 <= FailFast.errors.length
|
49
|
+
fail "\ne2f\nshould have raised only a #{kind} error for #{key}\n#{FailFast.errors.join("\n")}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
def it_should_raise_a_direct_error(value, kind, msg, &block)
|
56
|
+
it "should raise an error #{kind}-#{value}-#{msg}" do
|
57
|
+
begin
|
58
|
+
FailFast(SIMPLE_FILE_PATH).check do
|
59
|
+
raise "BUG : @@errorz should be empty \n#{FailFast.errors.inspect}" unless FailFast.errors.empty?
|
60
|
+
self.instance_eval(&block)
|
61
|
+
end
|
62
|
+
rescue => e
|
63
|
+
# uncomment the next line after the refactoring/once error are no longer raise
|
64
|
+
# raise e
|
65
|
+
ensure
|
66
|
+
if FailFast.errors.empty?
|
67
|
+
fail "\ne2d\nshould have raised a #{kind} error for #{value} \n==#{e}"
|
68
|
+
elsif FailFast.errors.length == 1 && !FailFast.errors.first.has_value_and_kind?(value, kind)
|
69
|
+
fail "\ne2e\nshould have raised a #{kind.inspect} error for #{value.inspect}\n, but raised instead\n#{FailFast.errors.inspect}"
|
70
|
+
elsif 2 <= FailFast.errors.length
|
71
|
+
fail "\ne2f\nshould have raised only 1 #{kind} error for #{value}\nbut raised instead\n#{FailFast.errors.join("\n")}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.included(receiver)
|
81
|
+
receiver.extend(ClassMethods)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
Spec::Runner.configure do |config|
|
85
|
+
config.include(DSLMacros)
|
86
|
+
end
|