fail_fast 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|