appsent 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+
6
+ .yardoc/
7
+ doc/
8
+
9
+ .rvmrc
10
+
11
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,5 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - ree
5
+ script: "bundle exec rake spec features"
@@ -0,0 +1,2 @@
1
+ --no-private
2
+ --readme README.md
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in appsent.gemspec
4
+ gemspec
@@ -0,0 +1,40 @@
1
+ APPSENT - awesome config management solution [![Build Status](http://travis-ci.org/kucaahbe/appsent.png)](http://travis-ci.org/kucaahbe/appsent)
2
+ ================================================================================================================================================
3
+
4
+ Description
5
+ -----------
6
+
7
+ In every application (especially big apps, where a lot of people working on it) you need
8
+ to have many config files, where settings for different environments (development, test, and production as minimum),
9
+ and without some settings there application will fail, and sometime it takes long time to find where was mistake.
10
+ This gem provides easy way to handle loading different config files, validations for necessary config values, in a such way:
11
+ your application will not start until you fill all needed settings, and when you done you will have access to every your in a convenient way.
12
+
13
+ Usage
14
+ -----
15
+
16
+ Initialize application with config requirements:
17
+
18
+ require 'appsent'
19
+ AppSent.init(:path => 'config', :env => ENV['RACK_ENV']) do
20
+
21
+ # Hash-based config:
22
+ mongo_db_config do
23
+ host :type => String, :example => 'localhost', :desc => 'Host to connect to MongoDB'
24
+ port :type => Fixnum
25
+ pool_size :type => Fixnum
26
+ timeout :type => Fixnum
27
+ end
28
+
29
+ # Array-based config(TODO:block non-required):
30
+ exception_notification_recipients :type => Array
31
+
32
+ my_simple_config # config without special requirements, stupid but it can do so, why not?
33
+ end
34
+
35
+ Access to config values performs in a such way:
36
+
37
+ AppSent::MONGO_DB_CONFIG['host'] #=>'localhost'
38
+ AppSent::EXCEPTION_NOTIFICATION_RECIPIENTS #=>[...]
39
+
40
+ TODO: more doc
@@ -0,0 +1,13 @@
1
+ require 'bundler/setup'
2
+ require 'rspec/core/rake_task'
3
+ require 'cucumber'
4
+ require 'cucumber/rake/task'
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ task :default => :spec
8
+
9
+ RSpec::Core::RakeTask.new(:spec)
10
+
11
+ Cucumber::Rake::Task.new(:features) do |t|
12
+ t.cucumber_opts = "--format pretty"
13
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "appsent/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "appsent"
7
+ s.version = AppSent::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["kucaahbe"]
10
+ s.email = ["kucaahbe@ukr.net"]
11
+ s.homepage = "http://github.com/kucaahbe/appsent"
12
+ s.summary = %q{config management solution}
13
+ s.description = s.summary
14
+
15
+ s.rubyforge_project = "appsent"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_development_dependency 'yard'
23
+ s.add_development_dependency 'BlueCloth'
24
+ s.add_development_dependency 'RedCloth'
25
+ s.add_development_dependency 'rspec', '>= 2.0.0'
26
+ s.add_development_dependency 'aruba'
27
+ s.add_development_dependency 'rake'
28
+ end
@@ -0,0 +1,40 @@
1
+ APPSENT - awesome config management solution [![Build Status](http://travis-ci.org/kucaahbe/appsent.png)](http://travis-ci.org/kucaahbe/appsent)
2
+ ================================================================================================================================================
3
+
4
+ Description
5
+ -----------
6
+
7
+ In every application (especially big apps, where a lot of people working on it) you need
8
+ to have many config files, where settings for different environments (development, test, and production as minimum),
9
+ and without some settings there application will fail, and sometime it takes long time to find where was mistake.
10
+ This gem provides easy way to handle loading different config files, validations for necessary config values, in a such way:
11
+ your application will not start until you fill all needed settings, and when you done you will have access to every your in a convenient way.
12
+
13
+ Usage
14
+ -----
15
+
16
+ Initialize application with config requirements:
17
+
18
+ require 'appsent'
19
+ AppSent.init(:path => 'config', :env => ENV['RACK_ENV']) do
20
+
21
+ # Hash-based config:
22
+ mongo_db_config do
23
+ host :type => String, :example => 'localhost', :desc => 'Host to connect to MongoDB'
24
+ port :type => Fixnum
25
+ pool_size :type => Fixnum
26
+ timeout :type => Fixnum
27
+ end
28
+
29
+ # Array-based config(TODO:block non-required):
30
+ exception_notification_recipients :type => Array
31
+
32
+ my_simple_config # config without special requirements, stupid but it can do so, why not?
33
+ end
34
+
35
+ Access to config values performs in a such way:
36
+
37
+ AppSent::MONGO_DB_CONFIG['host'] #=>'localhost'
38
+ AppSent::EXCEPTION_NOTIFICATION_RECIPIENTS #=>[...]
39
+
40
+ TODO: more doc
@@ -0,0 +1,7 @@
1
+ When /^I add file named "([^"]*)"$/ do |filename|
2
+ When %{an empty file named "#{filename}"}
3
+ end
4
+
5
+ When /^I write to "([^"]*)" following:$/ do |filename, content|
6
+ When %{a file named "#{filename}" with:}, content
7
+ end
@@ -0,0 +1 @@
1
+ require 'aruba/cucumber'
@@ -0,0 +1,85 @@
1
+ Feature: Usage example
2
+ As ruby developer
3
+
4
+ I want my application to start only when all config files exist and have right values
5
+
6
+ and in this case I am using appsent
7
+
8
+ Background:
9
+ Given a file named "my_app.rb" with:
10
+ """
11
+ require 'appsent'
12
+
13
+ AppSent.init :path => 'config', :env => 'production' do
14
+ mongodb do
15
+ host :type => String, :example => 'localhost', :desc => 'Host to connect to MongoDB'
16
+ port :type => Fixnum, :example => 27017, :desc => 'MongoDB port'
17
+ pool_size :type => Fixnum
18
+ timeout :type => Fixnum
19
+ end
20
+ end
21
+
22
+ puts 'All stuff work!'
23
+ """
24
+
25
+ Scenario: config does not exists
26
+ When I run `ruby my_app.rb`
27
+ Then the output should contain:
28
+ """
29
+ missing config file 'config/mongodb.yml'
30
+ """
31
+
32
+ Scenario: Config has no environment(or config is wrong yml file(FIXME))
33
+ When I add file named "config/mongodb.yml"
34
+ And I run `ruby my_app.rb`
35
+ Then the output should contain:
36
+ """
37
+ config file 'config/mongodb.yml' has no 'production' environment
38
+ """
39
+
40
+ Scenario: required parameteres do not specified
41
+ When I write to "config/mongodb.yml" with:
42
+ """
43
+ production:
44
+ optional_value: temp
45
+ """
46
+ And I run `ruby my_app.rb`
47
+ Then the output should contain:
48
+ """
49
+ wrong config file 'config/mongodb.yml':
50
+ host: localhost # does not exists(Host to connect to MongoDB), String
51
+ port: 27017 # does not exists(MongoDB port), Fixnum
52
+ pool_size: # does not exists, Fixnum
53
+ timeout: # does not exists, Fixnum
54
+ """
55
+
56
+ Scenario: Some parameter is wrong
57
+ When I write to "config/mongodb.yml" following:
58
+ """
59
+ production:
60
+ host: 100500
61
+ port: 27017
62
+ pool_size: 1
63
+ timeout: 5
64
+ """
65
+ And I run `ruby my_app.rb`
66
+ Then the output should contain:
67
+ """
68
+ wrong config file 'config/mongodb.yml':
69
+ host: 100500 # wrong type,should be String(Host to connect to MongoDB)
70
+ """
71
+
72
+ Scenario: All config present and have right values
73
+ When I write to "config/mongodb.yml" following:
74
+ """
75
+ production:
76
+ host: 'somehost.com'
77
+ port: 27017
78
+ pool_size: 1
79
+ timeout: 5
80
+ """
81
+ And I run `ruby my_app.rb`
82
+ Then the output should contain:
83
+ """
84
+ All stuff work!
85
+ """
@@ -0,0 +1,72 @@
1
+ require 'appsent/tools'
2
+ require 'appsent/config_value'
3
+ require 'appsent/config_file'
4
+
5
+ class AppSent
6
+
7
+ class ConfigPathNotSet < ArgumentError; end
8
+ class EnvironmentNotSet < ArgumentError; end
9
+ class BlockRequired < StandardError; end
10
+ class Error < LoadError; end
11
+
12
+ @@config_path = nil
13
+ @@environment = nil
14
+ @@config_files = []
15
+
16
+ def self.init opts={},&block
17
+ raise ConfigPathNotSet unless opts[:path]
18
+ raise EnvironmentNotSet unless opts[:env]
19
+ raise BlockRequired unless block_given?
20
+
21
+ caller_filename = caller.first.split(':').first
22
+ @@config_path = File.expand_path(File.join(File.dirname(caller_filename),opts[:path]))
23
+ @@environment = opts[:env]
24
+
25
+ settings = self.new
26
+ settings.instance_exec(&block)
27
+ if settings.all_valid?
28
+ settings.load!
29
+ else
30
+ raise AppSent::Error, settings.full_error_message
31
+ end
32
+ end
33
+
34
+ def self.config_files
35
+ @@config_files
36
+ end
37
+
38
+ def self.config_path
39
+ @@config_path
40
+ end
41
+
42
+ def initialize
43
+ @configs=[]
44
+ end
45
+
46
+ def all_valid?
47
+ @configs.ask_all? { |conf_file| conf_file.valid? }
48
+ end
49
+
50
+ def load!
51
+ @configs.each do |config|
52
+ self.class.const_set(config.constantized,config.data)
53
+ end
54
+ end
55
+
56
+ def full_error_message
57
+ error_description = ''
58
+ @configs.each do |config|
59
+ error_description += config.error_message+"\n" unless config.valid?
60
+ end
61
+ "failed to load some configuration files\n\n"+error_description
62
+ end
63
+
64
+ private
65
+
66
+ def method_missing config, args={}, &block
67
+ config = config.to_s
68
+ @@config_files << config
69
+ @configs << ConfigFile.new(@@config_path,config,@@environment,args[:type],&block)
70
+ end
71
+
72
+ end
@@ -0,0 +1,71 @@
1
+ class AppSent
2
+ class ConfigFile
3
+ attr_reader :data
4
+
5
+ CONFIG_NOT_FOUND_ERROR_MSG = "missing config file '%s'"
6
+ ENVIRONMENT_NOT_FOUND_ERROR_MSG = "config file '%s' has no '%s' environment"
7
+ WRONG_CONFIG_ERROR_MSG = "wrong config file '%s':\n"
8
+
9
+ def initialize config_dir, config_file_name, environment, type, &block
10
+ @config_dir, @config_file_name, @environment, @type, @block = config_dir, config_file_name, (environment && environment.to_sym), type, block
11
+
12
+ @type ||= Hash
13
+ raise "params #{@type} and block given" if block_given? and not @type==Hash
14
+ @path_to_config = File.join(@config_dir,@config_file_name+'.yml')
15
+ end
16
+
17
+ def valid?
18
+ return @checked if defined?(@checked)
19
+
20
+ yaml_data = YAML.load_file(@path_to_config)
21
+ if yaml_data.is_a?(Hash)
22
+ yaml_data.symbolize_keys!
23
+ else
24
+ # yaml is not valid YAML file, TODO change error message
25
+ @self_error_msg = ENVIRONMENT_NOT_FOUND_ERROR_MSG % [relative_path_to_config,@environment]
26
+ return @checked = false
27
+ end
28
+
29
+ @data = yaml_data[@environment]
30
+
31
+ @checked = if @data.instance_of?(@type)
32
+ @data.symbolize_keys! if @type==Hash
33
+ if @block
34
+ self.instance_exec(&@block)
35
+ @self_error_msg = WRONG_CONFIG_ERROR_MSG % relative_path_to_config
36
+ options.ask_all? { |option| option.valid? }
37
+ else
38
+ true
39
+ end
40
+ else
41
+ false
42
+ end
43
+ rescue Errno::ENOENT
44
+ @self_error_msg = CONFIG_NOT_FOUND_ERROR_MSG % relative_path_to_config
45
+ @checked = false
46
+ end
47
+
48
+ def options
49
+ @options ||= []
50
+ end
51
+
52
+ def constantized
53
+ @config_file_name.upcase
54
+ end
55
+
56
+ def error_message
57
+ @self_error_msg += options.map { |o| o.valid? ? nil : o.error_message }.compact.join("\n")
58
+ end
59
+
60
+ private
61
+
62
+ def relative_path_to_config
63
+ @path_to_config.gsub(Dir.pwd+File::SEPARATOR,'')
64
+ end
65
+
66
+ def method_missing option, opts={}, &block
67
+ self.options << ConfigValue.new(option.to_s, opts[:type], @data[option.to_sym], opts[:desc], opts[:example], &block)
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,56 @@
1
+ class AppSent
2
+ class ConfigValue
3
+ attr_reader :parameter, :data_type, :data, :description, :example
4
+ attr_accessor :nesting
5
+
6
+ WRONG_DATA_TYPE_PASSED_MSG = "data type should be ruby class!"
7
+ VALUE_NOT_EXISTS_MSG = "does not exists"
8
+ VALUE_WRONG_TYPE_MSG = "wrong type,should be %s"
9
+ FULL_ERROR_MESSAGE = "%s: %s # %s%s%s"
10
+
11
+ # data => it's an actual data of parameter
12
+ def initialize parameter, data_type, data, description, example, &block
13
+ @parameter, @data_type, @data, @description, @example = (parameter.to_sym rescue parameter), data_type, data, description, example
14
+
15
+ @data_type ||= Hash
16
+ raise WRONG_DATA_TYPE_PASSED_MSG unless @data_type.is_a?(Class)
17
+ raise "params #{@data_type} and block given" if block_given? and not @data_type==Hash
18
+
19
+ @block = block
20
+ @nesting = 0
21
+ end
22
+
23
+ def valid?
24
+ return @checked if defined?(@checked)
25
+ @checked = if data.instance_of?(data_type)
26
+ if @block
27
+ data.symbolize_keys!
28
+ self.instance_exec(&@block)
29
+ child_options.any? { |option| option.valid? }
30
+ else
31
+ true
32
+ end
33
+ else
34
+ false
35
+ end
36
+ end
37
+
38
+ def child_options
39
+ @options ||= []
40
+ end
41
+
42
+ def error_message
43
+ desc = (description and "(#{description})")
44
+ actual_error_msg = (data ? VALUE_WRONG_TYPE_MSG % [data_type] : VALUE_NOT_EXISTS_MSG)
45
+ optional_type = (data ? '' : ', '+data_type.inspect)
46
+ ' '*(self.nesting+1)+FULL_ERROR_MESSAGE % [parameter, (data or example), actual_error_msg, desc, optional_type]
47
+ end
48
+
49
+ private
50
+
51
+ def method_missing option, opts={}
52
+ self.child_options << self.class.new(option.to_s, opts[:type], data[option.to_sym], opts[:desc], opts[:example])
53
+ self.child_options.last.nesting+=(self.nesting+1)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,18 @@
1
+ class Hash
2
+ # fix bug here
3
+ unless self.method_defined?(:symbolize_keys!)
4
+ def symbolize_keys!
5
+ self.keys.each { |key| self[(key.to_sym rescue key) || key] = self.delete(key) }
6
+ end
7
+ end
8
+ end
9
+
10
+ class Array
11
+ def ask_all? &block
12
+ result = []
13
+ self.each do |el|
14
+ result << block.call(el)
15
+ end
16
+ result.all?
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ class AppSent
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe "AppSent.init" do
4
+
5
+ before :each do
6
+ @right_params = { :path => 'fixtures', :env => 'test' }
7
+ @fixtures_path = File.expand_path(File.join(File.dirname(__FILE__),'fixtures'))
8
+ end
9
+
10
+ it "should require config path" do
11
+ @right_params.delete(:path)
12
+ expect { AppSent.init(@right_params) do; end }.to raise_exception(AppSent::ConfigPathNotSet)
13
+ end
14
+
15
+ it "should require environment variable" do
16
+ @right_params.delete(:env)
17
+ expect { AppSent.init(@right_params) do; end }.to raise_exception(AppSent::EnvironmentNotSet)
18
+ end
19
+
20
+ it "should require block" do
21
+ expect { AppSent.init(@right_params) }.to raise_exception(AppSent::BlockRequired)
22
+ end
23
+
24
+ it "should save config path to @@config_path" do
25
+ AppSent.init(@right_params) do; end
26
+ AppSent.config_path.should eq(@fixtures_path)
27
+ end
28
+
29
+ it "should save environment to @@environment" do
30
+ AppSent.init(@right_params) do; end
31
+ AppSent.send(:class_variable_get,:@@environment).should eq('test')
32
+ end
33
+
34
+ it "should save array of configs to @@configs" do
35
+ expect {
36
+ AppSent.init(@right_params) do
37
+ config1
38
+ config2
39
+ config3
40
+ end
41
+ }.to raise_exception(AppSent::Error)
42
+ AppSent.config_files.should eq(%w(config1 config2 config3))
43
+ end
44
+
45
+ it "should create corresponding constants with values" do
46
+ AppSent.init(@right_params) do
47
+ simple_config
48
+ database do
49
+ username :type => String
50
+ password :type => String
51
+ port :type => Fixnum
52
+ end
53
+
54
+ simple_config_with_just_type :type => Array
55
+ end
56
+
57
+ AppSent::SIMPLE_CONFIG.should eq({:a=>1, :b=>'2'})
58
+ AppSent::DATABASE.should eq({:username => 'user', :password => 'pass', :port => 100500})
59
+ AppSent::SIMPLE_CONFIG_WITH_JUST_TYPE.should eq([1,2,3])
60
+ end
61
+
62
+ end
63
+
64
+ describe 'AppSent.new' do
65
+
66
+ subject { AppSent.new }
67
+
68
+ %w(all_valid? load! full_error_message).each do |method|
69
+ it { should respond_to(method) }
70
+ end
71
+
72
+ end
@@ -0,0 +1,4 @@
1
+ test:
2
+ username: user
3
+ password: pass
4
+ port: 100500
@@ -0,0 +1,3 @@
1
+ test:
2
+ a: 1
3
+ :b: '2'
@@ -0,0 +1,4 @@
1
+ test:
2
+ - 1
3
+ - 2
4
+ - 3
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ describe AppSent::ConfigFile do
4
+
5
+ subject { described_class }
6
+
7
+ before :each do
8
+ @params = ['/path/to/config','config_name',:environment, Hash]
9
+ @fake_config_filename = '/path/to/config/config_name.yml'
10
+ end
11
+
12
+ context ".new" do
13
+
14
+ %w(valid? options constantized error_message).each do |method|
15
+ it { subject.new(*@params).should respond_to(method)}
16
+ end
17
+
18
+ it "should raise exception if type is not hash and block given" do
19
+ block = lambda {}
20
+ @params[-1] = Array
21
+ expect { subject.new(*@params,&block) }.to raise_exception(/params Array and block given/)
22
+ end
23
+
24
+ end
25
+
26
+ context "#valid?" do
27
+
28
+ context "should be true" do
29
+
30
+ it "if config exists and environment presence(without type)(no values)" do
31
+ YAML.should_receive(:load_file).once.with(@fake_config_filename).and_return('environment' => {:a=>100500})
32
+ subject.new(*@params).should be_valid
33
+ end
34
+
35
+ it "if config exists and environment presence(with type specified)(no values)" do
36
+ @params[-1]=Array
37
+ YAML.should_receive(:load_file).once.with(@fake_config_filename).and_return(:environment => [1,2,3])
38
+ subject.new(*@params).should be_valid
39
+ end
40
+
41
+ it "if config exists and environment presence(with values)" do
42
+ values_block = lambda {
43
+ value :type => String
44
+ }
45
+ YAML.should_receive(:load_file).once.with(@fake_config_filename).and_return('environment' => {:value=>'100500'})
46
+ subject.new(*@params,&values_block).should be_valid
47
+ end
48
+
49
+ end
50
+
51
+ context "should be false" do
52
+
53
+ it "if config does not exists" do
54
+ YAML.should_receive(:load_file).once.with(@fake_config_filename).and_raise(Errno::ENOENT)
55
+ end
56
+
57
+ it "if environment does not presence in config" do
58
+ YAML.should_receive(:load_file).once.with(@fake_config_filename).and_return('other_environment' => {:a=>100500})
59
+ end
60
+
61
+ it "if wrong type" do
62
+ @params[-1] = Array
63
+ YAML.should_receive(:load_file).once.with(@fake_config_filename).and_return(:environment => 123)
64
+ end
65
+
66
+ after :each do
67
+ subject.new(*@params).should_not be_valid
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+
74
+ end
@@ -0,0 +1,114 @@
1
+ require 'spec_helper'
2
+
3
+ describe AppSent::ConfigValue do
4
+
5
+ subject { described_class }
6
+
7
+ before :each do
8
+ @params = [ 'param_name', String, 'some string', 'description string', 'example string' ]
9
+ end
10
+
11
+ context ".new" do
12
+
13
+ %w(valid? child_options error_message).each do |method|
14
+ it { subject.new(*@params).should respond_to(method)}
15
+ end
16
+
17
+ it "should raise exception if unsupported type passed" do
18
+ expect { subject.new('parameter','asd','data',nil,nil) }.to raise_exception(/data type should be ruby class!/)
19
+ end
20
+
21
+ it "should raise exception if type is not hash and block given" do
22
+ block = lambda {}
23
+ @params[1] = Array
24
+ expect { subject.new(*@params,&block) }.to raise_exception(/params Array and block given/)
25
+ end
26
+
27
+ end
28
+
29
+ context "#valid?" do
30
+
31
+ context "should return false" do
32
+
33
+ it "if entry does not presence in config file" do
34
+ subject.new('paramname',String,nil,nil,nil).should_not be_valid
35
+ end
36
+
37
+ it "if data in config file has wrong type" do
38
+ subject.new('paramname',String,2,nil,nil).should_not be_valid
39
+ end
40
+
41
+ it "if child value is not valid" do
42
+ @params[1]=Hash
43
+ @params[2]={:value => 100500}
44
+ values_block = lambda {
45
+ value :type => String
46
+ }
47
+ subject.new(*@params,&values_block).should_not be_valid
48
+ end
49
+
50
+ end
51
+
52
+ context "should return true" do
53
+
54
+ it "if entry presence and has right type" do
55
+ subject.new(*@params).should be_valid
56
+ end
57
+
58
+ it "if valid itself and child values valid too" do
59
+ @params[1]=Hash
60
+ @params[2]={'value' => 'some data'}
61
+ values_block = lambda {
62
+ value :type => String
63
+ }
64
+ subject.new(*@params,&values_block).should be_valid
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+
71
+ context "#error_message" do
72
+
73
+ context "should generate correct error message when no data" do
74
+
75
+ it "with full description" do
76
+ subject.new('database',String,nil,'Database name','localhost').error_message.should eq(" database: localhost # does not exists(Database name), String")
77
+ end
78
+
79
+ it "without example value" do
80
+ subject.new('database',String,nil,'Database name',nil).error_message.should eq(" database: # does not exists(Database name), String")
81
+ end
82
+
83
+ it "without description" do
84
+ subject.new('database',String,nil,nil,'localhost').error_message.should eq(" database: localhost # does not exists, String")
85
+ end
86
+
87
+ it "without example and description" do
88
+ subject.new('database',String,nil,nil,nil).error_message.should eq(" database: # does not exists, String")
89
+ end
90
+
91
+ end
92
+
93
+ context "should generate correct error message when no data is of wrong type" do
94
+
95
+ it "with full description" do
96
+ subject.new('database',String,20,'Database name','localhost').error_message.should eq(" database: 20 # wrong type,should be String(Database name)")
97
+ end
98
+
99
+ it "without example value" do
100
+ subject.new('database',String,20,'Database name',nil).error_message.should eq(" database: 20 # wrong type,should be String(Database name)")
101
+ end
102
+
103
+ it "without description" do
104
+ subject.new('database',String,20,nil,'localhost').error_message.should eq(" database: 20 # wrong type,should be String")
105
+ end
106
+
107
+ it "without example and description" do
108
+ subject.new('database',String,20,nil,nil).error_message.should eq(" database: 20 # wrong type,should be String")
109
+ end
110
+
111
+ end
112
+
113
+ end
114
+ end
@@ -0,0 +1,17 @@
1
+ require 'rspec/core'
2
+
3
+ if defined?(SimpleCov)
4
+ SimpleCov.start do
5
+ add_group 'Main', '/lib/'
6
+ end
7
+ end
8
+
9
+ require 'appsent'
10
+
11
+ # Requires supporting files with custom matchers and macros, etc,
12
+ # in ./support/ and its subdirectories.
13
+ Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
14
+
15
+ RSpec.configure do |config|
16
+ config.mock_with :rspec
17
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe Array do
4
+
5
+ context "#ask_all?" do
6
+
7
+ let(:string_receiver) { double(String) }
8
+ let(:fixnum_receiver) { double(Fixnum) }
9
+ let(:good_mock_array) { [string_receiver,string_receiver,string_receiver] }
10
+ let(:bad_mock_array) { [string_receiver,fixnum_receiver,string_receiver] }
11
+ let(:good) { ['a','b','c'] }
12
+ let(:bad) { ['a',100,'c'] }
13
+
14
+ it "should ask all elements" do
15
+ string_receiver.should_receive(:class).exactly(3).times.and_return(String)
16
+ good_mock_array.ask_all? { |e| e.class == String }.should be_true
17
+ end
18
+
19
+ it "should ask all elements" do
20
+ string_receiver.should_receive(:class).twice.and_return(String)
21
+ fixnum_receiver.should_receive(:class).once.and_return(Fixnum)
22
+ bad_mock_array.ask_all? { |e| e.class == String }.should be_false
23
+ end
24
+
25
+ it "should return true" do
26
+ good.ask_all? { |e| e.class == String }.should be_true
27
+ end
28
+
29
+ it "should return false" do
30
+ bad.ask_all? { |e| e.class == String }.should be_false
31
+ end
32
+
33
+ end
34
+
35
+ end
metadata ADDED
@@ -0,0 +1,177 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: appsent
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - kucaahbe
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-07-29 00:00:00 +03:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :development
33
+ name: yard
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :development
47
+ name: BlueCloth
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ type: :development
61
+ name: RedCloth
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ prerelease: false
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 15
71
+ segments:
72
+ - 2
73
+ - 0
74
+ - 0
75
+ version: 2.0.0
76
+ type: :development
77
+ name: rspec
78
+ version_requirements: *id004
79
+ - !ruby/object:Gem::Dependency
80
+ prerelease: false
81
+ requirement: &id005 !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ hash: 3
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ type: :development
91
+ name: aruba
92
+ version_requirements: *id005
93
+ - !ruby/object:Gem::Dependency
94
+ prerelease: false
95
+ requirement: &id006 !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ hash: 3
101
+ segments:
102
+ - 0
103
+ version: "0"
104
+ type: :development
105
+ name: rake
106
+ version_requirements: *id006
107
+ description: config management solution
108
+ email:
109
+ - kucaahbe@ukr.net
110
+ executables: []
111
+
112
+ extensions: []
113
+
114
+ extra_rdoc_files: []
115
+
116
+ files:
117
+ - .gitignore
118
+ - .rspec
119
+ - .travis.yml
120
+ - .yardopts
121
+ - Gemfile
122
+ - README.md
123
+ - Rakefile
124
+ - appsent.gemspec
125
+ - features/README.md
126
+ - features/step_definitions/helper_steps.rb
127
+ - features/support/env.rb
128
+ - features/usage_example.feature
129
+ - lib/appsent.rb
130
+ - lib/appsent/config_file.rb
131
+ - lib/appsent/config_value.rb
132
+ - lib/appsent/tools.rb
133
+ - lib/appsent/version.rb
134
+ - spec/dsl_spec.rb
135
+ - spec/fixtures/database.yml
136
+ - spec/fixtures/simple_config.yml
137
+ - spec/fixtures/simple_config_with_just_type.yml
138
+ - spec/internal_api/config_file_spec.rb
139
+ - spec/internal_api/config_value_spec.rb
140
+ - spec/spec_helper.rb
141
+ - spec/tools_spec.rb
142
+ has_rdoc: true
143
+ homepage: http://github.com/kucaahbe/appsent
144
+ licenses: []
145
+
146
+ post_install_message:
147
+ rdoc_options: []
148
+
149
+ require_paths:
150
+ - lib
151
+ required_ruby_version: !ruby/object:Gem::Requirement
152
+ none: false
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ hash: 3
157
+ segments:
158
+ - 0
159
+ version: "0"
160
+ required_rubygems_version: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ hash: 3
166
+ segments:
167
+ - 0
168
+ version: "0"
169
+ requirements: []
170
+
171
+ rubyforge_project: appsent
172
+ rubygems_version: 1.6.2
173
+ signing_key:
174
+ specification_version: 3
175
+ summary: config management solution
176
+ test_files: []
177
+