appsent 0.0.3 → 0.0.4
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/README.md +5 -5
- data/Rakefile +11 -1
- data/features/README.md +5 -5
- data/features/array_with_nested_params.feature +5 -5
- data/features/full_example.feature +13 -13
- data/features/simple_usage.feature +2 -2
- data/features/with_nested_params.feature +3 -3
- data/lib/appsent.rb +2 -2
- data/lib/appsent/config_file.rb +6 -5
- data/lib/appsent/config_value.rb +28 -6
- data/lib/appsent/version.rb +1 -1
- data/spec/{internal_api → appsent}/config_file_spec.rb +71 -1
- data/spec/appsent/config_value_spec.rb +234 -0
- data/spec/appsent_spec.rb +140 -0
- data/spec/old_api/dsl_spec.rb +135 -0
- data/spec/old_api/internal_api/config_file_spec.rb +222 -0
- data/spec/{internal_api → old_api/internal_api}/config_value_spec.rb +65 -17
- metadata +22 -19
- data/spec/dsl_spec.rb +0 -72
data/README.md
CHANGED
@@ -20,13 +20,13 @@ Initialize application with config requirements:
|
|
20
20
|
|
21
21
|
# Hash-based config:
|
22
22
|
mongo_db_config do
|
23
|
-
host
|
24
|
-
port
|
25
|
-
pool_size
|
26
|
-
timeout
|
23
|
+
host String, 'Host to connect to MongoDB' => 'localhost'
|
24
|
+
port Fixnum, 'Port to connect to MongoDB'
|
25
|
+
pool_size Fixnum
|
26
|
+
timeout Fixnum
|
27
27
|
end
|
28
28
|
|
29
|
-
exception_notification_recipients
|
29
|
+
exception_notification_recipients Array
|
30
30
|
|
31
31
|
end
|
32
32
|
|
data/Rakefile
CHANGED
@@ -6,7 +6,17 @@ Bundler::GemHelper.install_tasks
|
|
6
6
|
|
7
7
|
task :default => [:spec, :features]
|
8
8
|
|
9
|
-
RSpec::Core::RakeTask.new(:spec)
|
9
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
10
|
+
t.rspec_opts='--tag ~wip'
|
11
|
+
end
|
12
|
+
|
13
|
+
namespace :spec do
|
14
|
+
|
15
|
+
RSpec::Core::RakeTask.new(:wip) do |t|
|
16
|
+
t.rspec_opts='--tag wip'
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
10
20
|
|
11
21
|
Cucumber::Rake::Task.new(:features) do |t|
|
12
22
|
t.profile = 'default'
|
data/features/README.md
CHANGED
@@ -20,13 +20,13 @@ Initialize application with config requirements:
|
|
20
20
|
|
21
21
|
# Hash-based config:
|
22
22
|
mongo_db_config do
|
23
|
-
host
|
24
|
-
port
|
25
|
-
pool_size
|
26
|
-
timeout
|
23
|
+
host String, 'Host to connect to MongoDB' => 'localhost'
|
24
|
+
port Fixnum, 'Port to connect to MongoDB'
|
25
|
+
pool_size Fixnum
|
26
|
+
timeout Fixnum
|
27
27
|
end
|
28
28
|
|
29
|
-
exception_notification_recipients
|
29
|
+
exception_notification_recipients Array
|
30
30
|
|
31
31
|
end
|
32
32
|
|
@@ -9,12 +9,12 @@ Feature: Array with nested params
|
|
9
9
|
AppSent.init :path => 'config', :env => 'production' do
|
10
10
|
|
11
11
|
mongodb do
|
12
|
-
host
|
13
|
-
port
|
12
|
+
host String, 'Host to connect to MongoDB' => 'localhost'
|
13
|
+
port Fixnum, 'MongoDB port' => 27017
|
14
14
|
|
15
|
-
slaves
|
16
|
-
host
|
17
|
-
port
|
15
|
+
slaves Array do
|
16
|
+
host String, 'mongo slave host' => 'host.com'
|
17
|
+
port Fixnum, 'mongo slave port' => 27018
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -9,20 +9,20 @@ Feature: Complex usage
|
|
9
9
|
system_config do
|
10
10
|
|
11
11
|
google_analytics do
|
12
|
-
code
|
13
|
-
multiple_domains
|
14
|
-
domain
|
12
|
+
code String, 'Enter your google analytics code here' => 'UA-12345678-1'
|
13
|
+
multiple_domains String, 'has multiple domains?'
|
14
|
+
domain String, 'your domain' => 'example.com'
|
15
15
|
end
|
16
16
|
|
17
|
-
system_email
|
17
|
+
system_email String, :example => 'admin@example.com'
|
18
18
|
|
19
19
|
end
|
20
20
|
|
21
21
|
mongodb do
|
22
|
-
host
|
23
|
-
port
|
24
|
-
pool_size
|
25
|
-
timeout
|
22
|
+
host String, 'Host to connect to MongoDB' => 'localhost'
|
23
|
+
port Fixnum, 'MongoDB port' => 27017
|
24
|
+
pool_size Fixnum
|
25
|
+
timeout Fixnum
|
26
26
|
end
|
27
27
|
|
28
28
|
end
|
@@ -31,14 +31,14 @@ Feature: Complex usage
|
|
31
31
|
"""
|
32
32
|
# TODO:
|
33
33
|
#recaptcha :skip_env => true do
|
34
|
-
# recaptcha_public_key
|
35
|
-
# recaptcha_private_key
|
34
|
+
# recaptcha_public_key String, 'Recaptcha public key'
|
35
|
+
# recaptcha_private_key String, 'Recaptcha private key'
|
36
36
|
#end
|
37
|
-
#notification_recipients
|
37
|
+
#notification_recipients Array, :skip_env => true, :each_value => TODO
|
38
38
|
#
|
39
39
|
# slaves :type => Array do
|
40
|
-
# host
|
41
|
-
# port
|
40
|
+
# host String, 'mongo slave host' => 'host.com'
|
41
|
+
# port Fixnum, 'mongo slave port' => 27018
|
42
42
|
# end
|
43
43
|
|
44
44
|
Scenario: All config present and have right values
|
@@ -7,8 +7,8 @@ Feature: Simple usage example
|
|
7
7
|
|
8
8
|
AppSent.init :path => 'config', :env => 'production' do
|
9
9
|
mongodb do
|
10
|
-
host
|
11
|
-
port
|
10
|
+
host String, 'Host to connect to MongoDB' => 'localhost'
|
11
|
+
port Fixnum, 'MongoDB port' => 27017
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -9,9 +9,9 @@ Feature: Usage with nested params example
|
|
9
9
|
system_config do
|
10
10
|
|
11
11
|
google_analytics do
|
12
|
-
code
|
13
|
-
multiple_domains
|
14
|
-
domain
|
12
|
+
code String, 'Enter your google analytics code here' => 'UA-12345678-1'
|
13
|
+
multiple_domains String, 'has multiple domains?'
|
14
|
+
domain String, 'your domain' => 'example.com'
|
15
15
|
end
|
16
16
|
|
17
17
|
end
|
data/lib/appsent.rb
CHANGED
@@ -63,10 +63,10 @@ class AppSent
|
|
63
63
|
|
64
64
|
private
|
65
65
|
|
66
|
-
def method_missing config, args
|
66
|
+
def method_missing config, *args, &block
|
67
67
|
config = config.to_s
|
68
68
|
@@config_files << config
|
69
|
-
@configs << ConfigFile.new(@@config_path,config,@@environment
|
69
|
+
@configs << ConfigFile.new(@@config_path,config,@@environment,*args,&block)
|
70
70
|
end
|
71
71
|
|
72
72
|
end
|
data/lib/appsent/config_file.rb
CHANGED
@@ -6,10 +6,11 @@ class AppSent
|
|
6
6
|
ENVIRONMENT_NOT_FOUND_ERROR_MSG = "config file '%s' has no '%s' environment"
|
7
7
|
WRONG_CONFIG_ERROR_MSG = "wrong config file '%s':\n"
|
8
8
|
|
9
|
-
def initialize config_dir, config_file_name, environment,
|
10
|
-
@config_dir, @config_file_name, @environment, @
|
9
|
+
def initialize config_dir, config_file_name, environment, *opts, &block
|
10
|
+
@config_dir, @config_file_name, @environment, @block = config_dir, config_file_name, (environment && environment.to_sym), block
|
11
11
|
|
12
|
-
@type
|
12
|
+
@type = opts.empty? ? Hash : opts.first
|
13
|
+
@type = @type[:type] if @type.is_a?(Hash)
|
13
14
|
raise "params #{@type} and block given" if block_given? and not @type==Hash
|
14
15
|
@path_to_config = File.join(@config_dir,@config_file_name+'.yml')
|
15
16
|
@self_error_msg = ''
|
@@ -65,8 +66,8 @@ class AppSent
|
|
65
66
|
@path_to_config.gsub(Dir.pwd+File::SEPARATOR,'')
|
66
67
|
end
|
67
68
|
|
68
|
-
def method_missing option,
|
69
|
-
self.options << ConfigValue.new(option.to_s,
|
69
|
+
def method_missing option, *args, &block
|
70
|
+
self.options << ConfigValue.new(option.to_s, @data[option.to_sym], *args, &block)
|
70
71
|
end
|
71
72
|
|
72
73
|
end
|
data/lib/appsent/config_value.rb
CHANGED
@@ -10,8 +10,31 @@ class AppSent
|
|
10
10
|
WRONG_CHILD_OPTIONS_MSG = "wrong nested parameters"
|
11
11
|
|
12
12
|
# data => it's an actual data of parameter
|
13
|
-
def initialize parameter,
|
14
|
-
@parameter, @
|
13
|
+
def initialize parameter, data, *opts, &block
|
14
|
+
@parameter, @data = (parameter and parameter.to_sym), data
|
15
|
+
|
16
|
+
if opts.size==1
|
17
|
+
opts = opts.first
|
18
|
+
begin
|
19
|
+
%w( type desc example ).each do |deprecated_key|
|
20
|
+
warn("AppSent DEPRECATION WARNING: :#{deprecated_key} is deprecated and will be removed in a future major release, go to online documentation and see how to define config values") if opts.has_key?(deprecated_key.to_sym)
|
21
|
+
end
|
22
|
+
|
23
|
+
@data_type, @description, @example = opts[:type], opts[:desc], opts[:example]
|
24
|
+
rescue NoMethodError# opts is a [String]
|
25
|
+
@data_type = opts
|
26
|
+
end
|
27
|
+
else
|
28
|
+
@data_type = opts.delete_at(0)
|
29
|
+
description_and_example = opts.delete_at(0)
|
30
|
+
case description_and_example
|
31
|
+
when String
|
32
|
+
@description = description_and_example
|
33
|
+
when Hash
|
34
|
+
@description = description_and_example.keys.first
|
35
|
+
@example = description_and_example.values.first
|
36
|
+
end
|
37
|
+
end
|
15
38
|
|
16
39
|
@data_type ||= Hash
|
17
40
|
raise WRONG_DATA_TYPE_PASSED_MSG unless @data_type.is_a?(Class)
|
@@ -83,13 +106,12 @@ class AppSent
|
|
83
106
|
|
84
107
|
private
|
85
108
|
|
86
|
-
def method_missing option, opts
|
109
|
+
def method_missing option, *opts, &block
|
87
110
|
self.child_options << self.class.new(
|
88
111
|
option.to_s,
|
89
|
-
opts[:type],
|
90
112
|
data[option.to_sym],
|
91
|
-
opts
|
92
|
-
|
113
|
+
*opts,
|
114
|
+
&block
|
93
115
|
)
|
94
116
|
self.child_options.last.nesting+=(self.nesting+1)
|
95
117
|
end
|
data/lib/appsent/version.rb
CHANGED
@@ -30,6 +30,76 @@ describe AppSent::ConfigFile do
|
|
30
30
|
it { subject.new(*params).should respond_to(method)}
|
31
31
|
end
|
32
32
|
|
33
|
+
context "should send right variables to AppSent::ConfigValue" do
|
34
|
+
|
35
|
+
let(:mock_config_value) { mock(AppSent::ConfigValue, :valid? => true) }
|
36
|
+
|
37
|
+
it "in a simple case" do
|
38
|
+
AppSent::ConfigValue.should_receive(:new).once.with(
|
39
|
+
'username',
|
40
|
+
'user', # data
|
41
|
+
String
|
42
|
+
).and_return(mock_config_value)
|
43
|
+
|
44
|
+
AppSent.init(:path => '../fixtures', :env => 'test') do
|
45
|
+
database do
|
46
|
+
username String
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "with a &block" do
|
52
|
+
block = lambda {}
|
53
|
+
AppSent::ConfigValue.should_receive(:new).once.with(
|
54
|
+
'username',
|
55
|
+
'user', # data
|
56
|
+
String,
|
57
|
+
&block
|
58
|
+
).and_return(mock_config_value)
|
59
|
+
|
60
|
+
AppSent.init(:path => '../fixtures', :env => 'test') do
|
61
|
+
database do
|
62
|
+
username String, &block
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it "with description" do
|
68
|
+
AppSent::ConfigValue.should_receive(:new).once.with(
|
69
|
+
'username',
|
70
|
+
'user', # data
|
71
|
+
String,
|
72
|
+
'description'
|
73
|
+
).and_return(mock_config_value)
|
74
|
+
|
75
|
+
AppSent.init(:path => '../fixtures', :env => 'test') do
|
76
|
+
database do
|
77
|
+
username String, 'description'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it "with description and example" do
|
83
|
+
AppSent::ConfigValue.should_receive(:new).once.with(
|
84
|
+
'username',
|
85
|
+
'user', # data
|
86
|
+
String,
|
87
|
+
'description' => 'user'
|
88
|
+
).and_return(mock_config_value)
|
89
|
+
|
90
|
+
AppSent.init(:path => '../fixtures', :env => 'test') do
|
91
|
+
database do
|
92
|
+
username String, 'description' => 'user'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
after :each do
|
100
|
+
AppSent.send :remove_const, 'DATABASE' if AppSent.const_defined?("DATABASE")
|
101
|
+
end
|
102
|
+
|
33
103
|
end
|
34
104
|
|
35
105
|
context "#valid?" do
|
@@ -49,7 +119,7 @@ describe AppSent::ConfigFile do
|
|
49
119
|
|
50
120
|
it "if config exists and environment presence(with values)" do
|
51
121
|
values_block = lambda {
|
52
|
-
value
|
122
|
+
value String
|
53
123
|
}
|
54
124
|
YAML.should_receive(:load_file).once.with(fake_config_filename).and_return('environment' => {:value=>'100500'})
|
55
125
|
subject.new(*params,&values_block).should be_valid
|
@@ -0,0 +1,234 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AppSent::ConfigValue do
|
4
|
+
|
5
|
+
subject { described_class }
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
@params = {
|
9
|
+
'name' => 'param_name',
|
10
|
+
'type' => String,
|
11
|
+
'value' => 'some string',
|
12
|
+
'desc' => 'description string',
|
13
|
+
'example' => 'example'
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:params) do
|
18
|
+
result = [
|
19
|
+
@params['name'],
|
20
|
+
@params['value'],
|
21
|
+
@params['type']
|
22
|
+
]
|
23
|
+
if @params.has_key?('example')
|
24
|
+
result << { @params['desc'] => @params['example'] }
|
25
|
+
else
|
26
|
+
result << @params['desc']
|
27
|
+
end
|
28
|
+
result
|
29
|
+
end
|
30
|
+
|
31
|
+
context ".new" do
|
32
|
+
|
33
|
+
%w(valid? child_options error_message).each do |method|
|
34
|
+
it { subject.new(*params).should respond_to(method)}
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should raise exception if unsupported type passed" do
|
38
|
+
@params['type'] = 'asd'
|
39
|
+
expect { subject.new(*params) }.to raise_exception(/data type should be ruby class!/)
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with &block given" do
|
43
|
+
|
44
|
+
let(:block) do
|
45
|
+
lambda { value String }
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should not raise exception if data type is Array" do
|
49
|
+
@params['type'] = Array
|
50
|
+
expect { subject.new(*params,&block) }.to_not raise_exception(/params Array and block given/)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should not raise exception if data type is Hash" do
|
54
|
+
@params['type'] = Hash
|
55
|
+
expect { subject.new(*params,&block) }.to_not raise_exception(/params Hash and block given/)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should raise exception if data type is not Hash" do
|
59
|
+
@params['type'] = Fixnum
|
60
|
+
expect { subject.new(*params,&block) }.to raise_exception(/params Fixnum and block given/)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
context "#valid?" do
|
68
|
+
|
69
|
+
context "should return false" do
|
70
|
+
|
71
|
+
it "if entry does not presence in config file" do
|
72
|
+
@params['value']=nil
|
73
|
+
subject.new(*params).should_not be_valid
|
74
|
+
end
|
75
|
+
|
76
|
+
it "if data in config file has wrong type" do
|
77
|
+
@params['type']=Array
|
78
|
+
@params['value']='string'
|
79
|
+
subject.new(*params).should_not be_valid
|
80
|
+
end
|
81
|
+
|
82
|
+
it "if child value is not valid" do
|
83
|
+
@params['type']=Hash
|
84
|
+
@params['value']={:value => 100500}
|
85
|
+
values_block = lambda {
|
86
|
+
value String
|
87
|
+
}
|
88
|
+
subject.new(*params,&values_block).should_not be_valid
|
89
|
+
end
|
90
|
+
|
91
|
+
context "with type => Array", :wip => true do
|
92
|
+
|
93
|
+
it "if actual data is not array" do
|
94
|
+
@params['type']=Array
|
95
|
+
@params['value']=123
|
96
|
+
subject.new(*params).should_not be_valid
|
97
|
+
end
|
98
|
+
|
99
|
+
it "if actual data is an array of wrong hashes" do
|
100
|
+
@params['type']=Array
|
101
|
+
@params['value']=[1,2]
|
102
|
+
values_block = lambda {
|
103
|
+
value1 String
|
104
|
+
value2 Fixnum
|
105
|
+
}
|
106
|
+
subject.new(*params,&values_block).should_not be_valid
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
context "should return true" do
|
114
|
+
|
115
|
+
it "if entry presence and has right type" do
|
116
|
+
subject.new(*params).should be_valid
|
117
|
+
end
|
118
|
+
|
119
|
+
it "if valid itself and child values valid too" do
|
120
|
+
@params['type']=Hash
|
121
|
+
@params['value']={'value' => 'some data'}
|
122
|
+
values_block = lambda {
|
123
|
+
value String
|
124
|
+
}
|
125
|
+
subject.new(*params,&values_block).should be_valid
|
126
|
+
end
|
127
|
+
|
128
|
+
context "with type => Array", :wip => true do
|
129
|
+
|
130
|
+
it "if actual data is an array of right hashes" do
|
131
|
+
@params['type']=Array
|
132
|
+
@params['value']=[
|
133
|
+
{'value1' =>'qwe', 'value2' => 123 },
|
134
|
+
{'value1' =>'rty', 'value2' => 456 }
|
135
|
+
]
|
136
|
+
values_block = lambda {
|
137
|
+
value1 String
|
138
|
+
value2 Fixnum
|
139
|
+
}
|
140
|
+
subject.new(*params,&values_block).should be_valid
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
context "#error_message" do
|
150
|
+
|
151
|
+
subject { described_class.new(*params) }
|
152
|
+
|
153
|
+
context "should generate correct error message when no data" do
|
154
|
+
|
155
|
+
it "with full description" do
|
156
|
+
@params['name'] = 'database'
|
157
|
+
@params['value'] = nil
|
158
|
+
@params['type'] = String
|
159
|
+
@params['desc'] = 'Database name'
|
160
|
+
@params['example'] = 'localhost'
|
161
|
+
subject.error_message.should eq(" database: localhost # does not exists(Database name), String")
|
162
|
+
end
|
163
|
+
|
164
|
+
it "without example value" do
|
165
|
+
@params['name'] = 'database'
|
166
|
+
@params['value'] = nil
|
167
|
+
@params['type'] = String
|
168
|
+
@params['desc'] = 'Database name'
|
169
|
+
@params.delete('example')
|
170
|
+
subject.error_message.should eq(" database: # does not exists(Database name), String")
|
171
|
+
end
|
172
|
+
|
173
|
+
it "without description" do
|
174
|
+
@params['name'] = 'database'
|
175
|
+
@params['value'] = nil
|
176
|
+
@params['type'] = String
|
177
|
+
@params.delete('desc')
|
178
|
+
@params['example'] = 'localhost'
|
179
|
+
subject.error_message.should eq(" database: localhost # does not exists, String")
|
180
|
+
end
|
181
|
+
|
182
|
+
it "without example and description" do
|
183
|
+
@params['name'] = 'database'
|
184
|
+
@params['value'] = nil
|
185
|
+
@params['type'] = String
|
186
|
+
@params.delete('desc')
|
187
|
+
@params.delete('example')
|
188
|
+
subject.error_message.should eq(" database: # does not exists, String")
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
|
193
|
+
context "should generate correct error message when data is of wrong type" do
|
194
|
+
|
195
|
+
it "with full description" do
|
196
|
+
@params['name'] = 'database'
|
197
|
+
@params['value'] = 20
|
198
|
+
@params['type'] = String
|
199
|
+
@params['desc'] = 'Database name'
|
200
|
+
@params['example'] = 'localhost'
|
201
|
+
subject.error_message.should eq(" database: 20 # wrong type,should be String(Database name)")
|
202
|
+
end
|
203
|
+
|
204
|
+
it "without example value" do
|
205
|
+
@params['name'] = 'database'
|
206
|
+
@params['value'] = 20
|
207
|
+
@params['type'] = String
|
208
|
+
@params['desc'] = 'Database name'
|
209
|
+
@params.delete('example')
|
210
|
+
subject.error_message.should eq(" database: 20 # wrong type,should be String(Database name)")
|
211
|
+
end
|
212
|
+
|
213
|
+
it "without description" do
|
214
|
+
@params['name'] = 'database'
|
215
|
+
@params['value'] = 20
|
216
|
+
@params['type'] = String
|
217
|
+
@params.delete('desc')
|
218
|
+
@params['example'] = 'localhost'
|
219
|
+
subject.error_message.should eq(" database: 20 # wrong type,should be String")
|
220
|
+
end
|
221
|
+
|
222
|
+
it "without example and description" do
|
223
|
+
@params['name'] = 'database'
|
224
|
+
@params['value'] = 20
|
225
|
+
@params['type'] = String
|
226
|
+
@params.delete('desc')
|
227
|
+
@params.delete('example')
|
228
|
+
subject.error_message.should eq(" database: 20 # wrong type,should be String")
|
229
|
+
end
|
230
|
+
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
234
|
+
end
|