hetznerza-settingslogic 2.0.9

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 29e66c9f18fae9d17b64e89ce70e4f3ef168d73b
4
+ data.tar.gz: c1f856be55a3359f424947335aa6b42faaaef19c
5
+ SHA512:
6
+ metadata.gz: 45d8fe95a3c0ad42d4f30d743a12290100fae30b53dbbc22997df7e49362be046b8ee1ef24fb3dd35367ba24722b49c63ca3c71ec773c0376f64c828f77852b9
7
+ data.tar.gz: 36e793c3db4f6864afa1664b4b449ad70a3cf018d4e946912186abc2e70be880425feb6adc9e47f2db212f95689a19904f08f4e743c8fca7ec55fcd8e0b74769
@@ -0,0 +1,10 @@
1
+ .DS_Store
2
+ *.log
3
+ *.sqlite3
4
+ pkg/*
5
+ coverage/*
6
+ doc/*
7
+ benchmarks/*
8
+ .bundle
9
+ vendor/bundle
10
+ .rvmrc
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - 2.1.2
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
@@ -0,0 +1,26 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ hetznerza-settingslogic (2.0.9)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.3)
10
+ rake (10.0.3)
11
+ rspec (2.12.0)
12
+ rspec-core (~> 2.12.0)
13
+ rspec-expectations (~> 2.12.0)
14
+ rspec-mocks (~> 2.12.0)
15
+ rspec-core (2.12.2)
16
+ rspec-expectations (2.12.1)
17
+ diff-lcs (~> 1.1.3)
18
+ rspec-mocks (2.12.1)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ hetznerza-settingslogic!
25
+ rake
26
+ rspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Ben Johnson of Binary Logic (binarylogic.com)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,161 @@
1
+ = Settingslogic
2
+
3
+ Settingslogic is a simple configuration / settings solution that uses an ERB enabled YAML file. It has been great for
4
+ our apps, maybe you will enjoy it too. Settingslogic works with Rails, Sinatra, or any Ruby project.
5
+
6
+ {<img src="https://badge.fury.io/rb/settingslogic.svg" alt="Gem Version" />}[http://badge.fury.io/rb/settingslogic]
7
+ {<img src="https://travis-ci.org/settingslogic/settingslogic.svg" alt="Build Status" />}[https://travis-ci.org/settingslogic/settingslogic]
8
+ {<img src="http://inch-ci.org/github/settingslogic/settingslogic.png?branch=master" alt="Inline docs" />}[http://inch-ci.org/github/settingslogic/settingslogic]
9
+
10
+ == Helpful links
11
+
12
+ * <b>Documentation:</b> http://rdoc.info/github/settingslogic/settingslogic
13
+ * <b>Repository:</b> http://github.com/settingslogic/settingslogic/tree/master
14
+ * <b>Issues:</b> http://github.com/settingslogic/settingslogic/issues
15
+
16
+ == Installation
17
+
18
+ gem install settingslogic
19
+
20
+ == Usage
21
+
22
+ === 1. Define your class
23
+
24
+ Instead of defining a Settings constant for you, that task is left to you. Simply create a class in your application
25
+ that looks like:
26
+
27
+ class Settings < Settingslogic
28
+ source "#{Rails.root}/config/application.yml"
29
+ namespace Rails.env
30
+ end
31
+
32
+ Name it Settings, name it Config, name it whatever you want. Add as many or as few as you like. A good place to put
33
+ this file in a rails app is app/models/settings.rb
34
+
35
+ I felt adding a settings file in your app was more straightforward, less tricky, and more flexible.
36
+
37
+ === 2. Create your settings
38
+
39
+ Notice above we specified an absolute path to our settings file called "application.yml". This is just a typical YAML file.
40
+ Also notice above that we specified a namespace for our environment. A namespace is just an optional string that corresponds
41
+ to a key in the YAML file.
42
+
43
+ Using a namespace allows us to change our configuration depending on our environment:
44
+
45
+ # config/application.yml
46
+ defaults: &defaults
47
+ cool:
48
+ saweet: nested settings
49
+ neat_setting: 24
50
+ awesome_setting: <%= "Did you know 5 + 5 = #{5 + 5}?" %>
51
+
52
+ development:
53
+ <<: *defaults
54
+ neat_setting: 800
55
+
56
+ test:
57
+ <<: *defaults
58
+
59
+ production:
60
+ <<: *defaults
61
+
62
+ _Note_: Certain Ruby/Bundler versions include a version of the Psych YAML parser which incorrectly handles merges (the `<<` in the example above.)
63
+ If your default settings seem to be overwriting your environment-specific settings, including the following lines in your config/boot.rb file may solve the problem:
64
+
65
+ require 'yaml'
66
+ YAML::ENGINE.yamler= 'syck'
67
+
68
+ === 3. Access your settings
69
+
70
+ >> Rails.env
71
+ => "development"
72
+
73
+ >> Settings.cool
74
+ => "#<Settingslogic::Settings ... >"
75
+
76
+ >> Settings.cool.saweet
77
+ => "nested settings"
78
+
79
+ >> Settings.neat_setting
80
+ => 800
81
+
82
+ >> Settings.awesome_setting
83
+ => "Did you know 5 + 5 = 10?"
84
+
85
+ You can use these settings anywhere, for example in a model:
86
+
87
+ class Post < ActiveRecord::Base
88
+ self.per_page = Settings.pagination.posts_per_page
89
+ end
90
+
91
+ === 4. Optional / dynamic settings
92
+
93
+ Often, you will want to handle defaults in your application logic itself, to reduce the number of settings
94
+ you need to put in your YAML file. You can access an optional setting by using Hash notation:
95
+
96
+ >> Settings.messaging.queue_name
97
+ => Exception: Missing setting 'queue_name' in 'message' section in 'application.yml'
98
+
99
+ >> Settings.messaging['queue_name']
100
+ => nil
101
+
102
+ >> Settings.messaging['queue_name'] ||= 'user_mail'
103
+ => "user_mail"
104
+
105
+ >> Settings.messaging.queue_name
106
+ => "user_mail"
107
+
108
+ Modifying our model example:
109
+
110
+ class Post < ActiveRecord::Base
111
+ self.per_page = Settings.posts['per_page'] || Settings.pagination.per_page
112
+ end
113
+
114
+ This would allow you to specify a custom value for per_page just for posts, or
115
+ to fall back to your default value if not specified.
116
+
117
+ === 5. Suppressing Exceptions Conditionally
118
+
119
+ Raising exceptions for missing settings helps highlight configuration problems. However, in a
120
+ Rails app it may make sense to suppress this in production and return nil for missing settings.
121
+ While it's useful to stop and highlight an error in development or test environments, this is
122
+ often not the right answer for production.
123
+
124
+ class Settings < Settingslogic
125
+ source "#{Rails.root}/config/application.yml"
126
+ namespace Rails.env
127
+ suppress_errors Rails.env.production?
128
+ end
129
+
130
+ >> Settings.non_existent_key
131
+ => nil
132
+
133
+ == Note on Sinatra / Capistrano / Vlad
134
+
135
+ Each of these frameworks uses a +set+ convention for settings, which actually defines methods
136
+ in the global Object namespace:
137
+
138
+ set :application, "myapp" # does "def application" globally
139
+
140
+ This can cause collisions with Settingslogic, since those methods are global. Luckily, the
141
+ solution is to just add a call to load! in your class:
142
+
143
+ class Settings < Settingslogic
144
+ source "#{Rails.root}/config/application.yml"
145
+ namespace Rails.env
146
+ load!
147
+ end
148
+
149
+ It's probably always safest to add load! to your class, since this guarantees settings will be
150
+ loaded at that time, rather than lazily later via method_missing.
151
+
152
+ Finally, you can reload all your settings later as well:
153
+
154
+ Settings.reload!
155
+
156
+ This is useful if you want to support changing your settings YAML without restarting your app.
157
+
158
+ == Author
159
+
160
+ Copyright (c) 2008-2010 {Ben Johnson}[http://github.com/binarylogic] of {Binary Logic}[http://www.binarylogic.com],
161
+ released under the MIT license. Support for optional settings and reloading by {Nate Wiger}[http://nate.wiger.org].
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new
6
+
7
+ task :default => :spec
@@ -0,0 +1,195 @@
1
+ require "yaml"
2
+ require "erb"
3
+ require 'open-uri'
4
+
5
+ # A simple settings solution using a YAML file. See README for more information.
6
+ class Settingslogic < Hash
7
+ class MissingSetting < StandardError; end
8
+
9
+ class << self
10
+ def name # :nodoc:
11
+ self.superclass != Hash && instance.key?("name") ? instance.name : super
12
+ end
13
+
14
+ # Enables Settings.get('nested.key.name') for dynamic access
15
+ def get(key)
16
+ parts = key.split('.')
17
+ curs = self
18
+ while p = parts.shift
19
+ curs = curs.send(p)
20
+ end
21
+ curs
22
+ end
23
+
24
+ def source(value = nil)
25
+ @source ||= value
26
+ end
27
+
28
+ def namespace(value = nil)
29
+ @namespace ||= value
30
+ end
31
+
32
+ def section(value = nil)
33
+ @section ||= value
34
+ end
35
+
36
+ def suppress_errors(value = nil)
37
+ @suppress_errors ||= value
38
+ end
39
+
40
+ def [](key)
41
+ instance.fetch(key.to_s, nil)
42
+ end
43
+
44
+ def []=(key, val)
45
+ # Setting[:key][:key2] = 'value' for dynamic settings
46
+ val = new(val, source) if val.is_a? Hash
47
+ instance.store(key.to_s, val)
48
+ instance.create_accessor_for(key, val)
49
+ end
50
+
51
+ def load!
52
+ instance
53
+ true
54
+ end
55
+
56
+ def reload!
57
+ @instance = nil
58
+ load!
59
+ end
60
+
61
+ private
62
+ def instance
63
+ return @instance if @instance
64
+ @instance = new
65
+ create_accessors!
66
+ @instance
67
+ end
68
+
69
+ def method_missing(name, *args, &block)
70
+ instance.send(name, *args, &block)
71
+ end
72
+
73
+ # It would be great to DRY this up somehow, someday, but it's difficult because
74
+ # of the singleton pattern. Basically this proxies Setting.foo to Setting.instance.foo
75
+ def create_accessors!
76
+ instance.each do |key,val|
77
+ create_accessor_for(key)
78
+ end
79
+ end
80
+
81
+ def create_accessor_for(key)
82
+ return unless key.to_s =~ /^\w+$/ # could have "some-setting:" which blows up eval
83
+ instance_eval "def #{key}; instance.send(:#{key}); end"
84
+ end
85
+
86
+ end
87
+
88
+ # Initializes a new settings object. You can initialize an object in any of the following ways:
89
+ #
90
+ # Settings.new(:application) # will look for config/application.yml
91
+ # Settings.new("application.yaml") # will look for application.yaml
92
+ # Settings.new("/var/configs/application.yml") # will look for /var/configs/application.yml
93
+ # Settings.new(:config1 => 1, :config2 => 2)
94
+ #
95
+ # Basically if you pass a symbol it will look for that file in the configs directory of your rails app,
96
+ # if you are using this in rails. If you pass a string it should be an absolute path to your settings file.
97
+ # Then you can pass a hash, and it just allows you to access the hash via methods.
98
+ def initialize(hash_or_file = self.class.source, section = self.class.section)
99
+ #puts "new! #{hash_or_file}"
100
+ case hash_or_file
101
+ when nil
102
+ raise Errno::ENOENT, "No file specified as Settingslogic source"
103
+ when Hash
104
+ self.replace hash_or_file
105
+ else
106
+ file_contents = open(hash_or_file).read
107
+ hash = file_contents.empty? ? {} : YAML.load(ERB.new(file_contents).result).to_hash
108
+ if self.class.namespace
109
+ hash = hash[self.class.namespace] or return missing_key("Missing setting '#{self.class.namespace}' in #{hash_or_file}")
110
+ end
111
+ self.replace hash
112
+ end
113
+ @section = section || "Hash" # so end of error says "in application.yml"
114
+ create_accessors!
115
+ end
116
+
117
+ # Called for dynamically-defined keys, and also the first key deferenced at the top-level, if load! is not used.
118
+ # Otherwise, create_accessors! (called by new) will have created actual methods for each key.
119
+ def method_missing(name, *args, &block)
120
+ key = name.to_s
121
+ return missing_key("Missing setting '#{key}' in #{@section}") unless has_key? key
122
+ value = fetch(key)
123
+ create_accessor_for(key)
124
+ value.is_a?(Hash) ? self.class.new(value, "'#{key}' section in #{@section}") : value
125
+ end
126
+
127
+ def [](key)
128
+ fetch(key.to_s, nil)
129
+ end
130
+
131
+ def []=(key,val)
132
+ # Setting[:key][:key2] = 'value' for dynamic settings
133
+ val = self.class.new(val, @section) if val.is_a? Hash
134
+ store(key.to_s, val)
135
+ create_accessor_for(key, val)
136
+ end
137
+
138
+ # Returns an instance of a Hash object
139
+ def to_hash
140
+ Hash[self]
141
+ end
142
+
143
+ # This handles naming collisions with Sinatra/Vlad/Capistrano. Since these use a set()
144
+ # helper that defines methods in Object, ANY method_missing ANYWHERE picks up the Vlad/Sinatra
145
+ # settings! So settings.deploy_to title actually calls Object.deploy_to (from set :deploy_to, "host"),
146
+ # rather than the app_yml['deploy_to'] hash. Jeezus.
147
+ def create_accessors!
148
+ self.each do |key,val|
149
+ create_accessor_for(key)
150
+ end
151
+ end
152
+
153
+ # Use instance_eval/class_eval because they're actually more efficient than define_method{}
154
+ # http://stackoverflow.com/questions/185947/ruby-definemethod-vs-def
155
+ # http://bmorearty.wordpress.com/2009/01/09/fun-with-rubys-instance_eval-and-class_eval/
156
+ def create_accessor_for(key, val=nil)
157
+ return unless key.to_s =~ /^\w+$/ # could have "some-setting:" which blows up eval
158
+ instance_variable_set("@#{key}", val)
159
+ self.class.class_eval <<-EndEval
160
+ def #{key}
161
+ return @#{key} if @#{key}
162
+ return missing_key("Missing setting '#{key}' in #{@section}") unless has_key? '#{key}'
163
+ value = fetch('#{key}')
164
+ @#{key} = if value.is_a?(Hash)
165
+ self.class.new(value, "'#{key}' section in #{@section}")
166
+ elsif value.is_a?(Array) && value.all?{|v| v.is_a? Hash}
167
+ value.map{|v| self.class.new(v)}
168
+ else
169
+ value
170
+ end
171
+ end
172
+ EndEval
173
+ end
174
+
175
+ def symbolize_keys
176
+
177
+ inject({}) do |memo, tuple|
178
+
179
+ k = (tuple.first.to_sym rescue tuple.first) || tuple.first
180
+
181
+ v = k.is_a?(Symbol) ? send(k) : tuple.last # make sure the value is accessed the same way Settings.foo.bar works
182
+
183
+ memo[k] = v && v.respond_to?(:symbolize_keys) ? v.symbolize_keys : v #recurse for nested hashes
184
+
185
+ memo
186
+ end
187
+
188
+ end
189
+
190
+ def missing_key(msg)
191
+ return nil if self.class.suppress_errors
192
+
193
+ raise MissingSetting, msg
194
+ end
195
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "hetznerza-settingslogic"
6
+ s.version = "2.0.9"
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["Ben Johnson"]
9
+ s.email = ["bjohnson@binarylogic.com"]
10
+ s.homepage = "http://github.com/hetznerZA/settingslogic"
11
+ s.summary = %q{A simple and straightforward settings solution that uses an ERB enabled YAML file and a singleton design pattern.}
12
+ s.description = %q{A simple and straightforward settings solution that uses an ERB enabled YAML file and a singleton design pattern.}
13
+
14
+ s.add_development_dependency 'rake'
15
+ s.add_development_dependency 'rspec'
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
+ end
@@ -0,0 +1,6 @@
1
+ class Settings < Settingslogic
2
+ source "#{File.dirname(__FILE__)}/settings.yml"
3
+ end
4
+
5
+ class SettingsInst < Settingslogic
6
+ end
@@ -0,0 +1,28 @@
1
+ setting1:
2
+ setting1_child: saweet
3
+ deep:
4
+ another: my value
5
+ child:
6
+ value: 2
7
+
8
+ setting2: 5
9
+ setting3: <%= 5 * 5 %>
10
+ name: test
11
+
12
+ language:
13
+ haskell:
14
+ paradigm: functional
15
+ smalltalk:
16
+ paradigm: object oriented
17
+
18
+ collides:
19
+ does: not
20
+ nested:
21
+ collides:
22
+ does: not either
23
+
24
+ array:
25
+ -
26
+ name: first
27
+ -
28
+ name: second
@@ -0,0 +1,4 @@
1
+ class Settings2 < Settingslogic
2
+ source "#{File.dirname(__FILE__)}/settings.yml"
3
+ namespace "setting1"
4
+ end
@@ -0,0 +1,4 @@
1
+ class Settings3 < Settingslogic
2
+ source "#{File.dirname(__FILE__)}/settings.yml"
3
+ load! # test of load
4
+ end
@@ -0,0 +1,4 @@
1
+ class Settings4 < Settingslogic
2
+ source "#{File.dirname(__FILE__)}/settings.yml"
3
+ suppress_errors true
4
+ end
@@ -0,0 +1,6 @@
1
+ require "yaml"
2
+
3
+ class Settings5 < Settingslogic
4
+ source YAML.load_file("#{File.dirname(__FILE__)}/settings.yml")
5
+ namespace "setting1"
6
+ end
@@ -0,0 +1,7 @@
1
+ require "yaml"
2
+
3
+ class Settings6 < Settingslogic
4
+ source YAML.load_file("#{File.dirname(__FILE__)}/settings.yml")
5
+ section "settings.yml"
6
+ namespace "setting1"
7
+ end
@@ -0,0 +1,3 @@
1
+ class SettingsEmpty < Settingslogic
2
+ source "#{File.dirname(__FILE__)}/settings_empty.yml"
3
+ end
File without changes
@@ -0,0 +1,229 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
2
+
3
+ describe "Settingslogic" do
4
+ it "should access settings" do
5
+ Settings.setting2.should == 5
6
+ end
7
+
8
+ it "should access nested settings" do
9
+ Settings.setting1.setting1_child.should == "saweet"
10
+ end
11
+
12
+ it "should access settings in nested arrays" do
13
+ Settings.array.first.name.should == "first"
14
+ end
15
+
16
+ it "should access deep nested settings" do
17
+ Settings.setting1.deep.another.should == "my value"
18
+ end
19
+
20
+ it "should access extra deep nested settings" do
21
+ Settings.setting1.deep.child.value.should == 2
22
+ end
23
+
24
+ it "should enable erb" do
25
+ Settings.setting3.should == 25
26
+ end
27
+
28
+ it "should namespace settings" do
29
+ Settings2.setting1_child.should == "saweet"
30
+ Settings2.deep.another.should == "my value"
31
+ end
32
+
33
+ it "should return the namespace" do
34
+ Settings.namespace.should be_nil
35
+ Settings2.namespace.should == 'setting1'
36
+ end
37
+
38
+ it "should distinguish nested keys" do
39
+ Settings.language.haskell.paradigm.should == 'functional'
40
+ Settings.language.smalltalk.paradigm.should == 'object oriented'
41
+ end
42
+
43
+ it "should not collide with global methods" do
44
+ Settings3.nested.collides.does.should == 'not either'
45
+ Settings3[:nested] = 'fooey'
46
+ Settings3[:nested].should == 'fooey'
47
+ Settings3.nested.should == 'fooey'
48
+ Settings3.collides.does.should == 'not'
49
+ end
50
+
51
+ it "should raise a helpful error message" do
52
+ e = nil
53
+ begin
54
+ Settings.missing
55
+ rescue => e
56
+ e.should be_kind_of Settingslogic::MissingSetting
57
+ end
58
+ e.should_not be_nil
59
+ e.message.should =~ /Missing setting 'missing' in/
60
+
61
+ e = nil
62
+ begin
63
+ Settings.language.missing
64
+ rescue => e
65
+ e.should be_kind_of Settingslogic::MissingSetting
66
+ end
67
+ e.should_not be_nil
68
+ e.message.should =~ /Missing setting 'missing' in 'language' section/
69
+ end
70
+
71
+ it "should handle optional / dynamic settings" do
72
+ e = nil
73
+ begin
74
+ Settings.language.erlang
75
+ rescue => e
76
+ e.should be_kind_of Settingslogic::MissingSetting
77
+ end
78
+ e.should_not be_nil
79
+ e.message.should =~ /Missing setting 'erlang' in 'language' section/
80
+
81
+ Settings.language['erlang'].should be_nil
82
+ Settings.language['erlang'] = 5
83
+ Settings.language['erlang'].should == 5
84
+
85
+ Settings.language['erlang'] = {'paradigm' => 'functional'}
86
+ Settings.language.erlang.paradigm.should == 'functional'
87
+ Settings.respond_to?('erlang').should be_false
88
+
89
+ Settings.reload!
90
+ Settings.language['erlang'].should be_nil
91
+
92
+ Settings.language[:erlang] ||= 5
93
+ Settings.language[:erlang].should == 5
94
+
95
+ Settings.language[:erlang] = {}
96
+ Settings.language[:erlang][:paradigm] = 'functional'
97
+ Settings.language.erlang.paradigm.should == 'functional'
98
+
99
+ Settings[:toplevel] = '42'
100
+ Settings.toplevel.should == '42'
101
+ end
102
+
103
+ it "should raise an error on a nil source argument" do
104
+ class NoSource < Settingslogic; end
105
+ e = nil
106
+ begin
107
+ NoSource.foo.bar
108
+ rescue => e
109
+ e.should be_kind_of Errno::ENOENT
110
+ end
111
+ e.should_not be_nil
112
+ end
113
+
114
+ it "should allow suppressing errors" do
115
+ Settings4.non_existent_key.should be_nil
116
+ end
117
+
118
+ # This one edge case currently does not pass, because it requires very
119
+ # esoteric code in order to make it pass. It was judged not worth fixing,
120
+ # as it introduces significant complexity for minor gain.
121
+ # it "should handle reloading top-level settings"
122
+ # Settings[:inspect] = 'yeah baby'
123
+ # Settings.inspect.should == 'yeah baby'
124
+ # Settings.reload!
125
+ # Settings.inspect.should == 'Settings'
126
+ # end
127
+
128
+ it "should handle oddly-named settings" do
129
+ Settings.language['some-dash-setting#'] = 'dashtastic'
130
+ Settings.language['some-dash-setting#'].should == 'dashtastic'
131
+ end
132
+
133
+ it "should handle settings with nil value" do
134
+ Settings["flag"] = true
135
+ Settings["flag"] = nil
136
+ Settings.flag.should == nil
137
+ end
138
+
139
+ it "should handle settings with false value" do
140
+ Settings["flag"] = true
141
+ Settings["flag"] = false
142
+ Settings.flag.should == false
143
+ end
144
+
145
+ it "should support instance usage as well" do
146
+ settings = SettingsInst.new(Settings.source)
147
+ settings.setting1.setting1_child.should == "saweet"
148
+ end
149
+
150
+ it "should handle Hash as source" do
151
+ Settings5.setting2.should == 5
152
+
153
+ e = nil
154
+ begin
155
+ Settings5.missing
156
+ rescue => e
157
+ e.should be_kind_of Settingslogic::MissingSetting
158
+ end
159
+ e.should_not be_nil
160
+ e.message.should =~ /Missing setting 'missing' in Hash/
161
+
162
+ e = nil
163
+ begin
164
+ Settings6.missing
165
+ rescue => e
166
+ e.should be_kind_of Settingslogic::MissingSetting
167
+ end
168
+ e.should_not be_nil
169
+ e.message.should =~ /Missing setting 'missing' in settings.yml/
170
+ end
171
+
172
+ it "should be able to get() a key with dot.notation" do
173
+ Settings.get('setting1.setting1_child').should == "saweet"
174
+ Settings.get('setting1.deep.another').should == "my value"
175
+ Settings.get('setting1.deep.child.value').should == 2
176
+ end
177
+
178
+ # If .name is not a property, delegate to superclass
179
+ it "should respond with Module.name" do
180
+ Settings2.name.should == "Settings2"
181
+ end
182
+
183
+ # If .name is called on Settingslogic itself, handle appropriately
184
+ # by delegating to Hash
185
+ it "should have the parent class always respond with Module.name" do
186
+ Settingslogic.name.should == 'Settingslogic'
187
+ end
188
+
189
+ # If .name is a property, respond with that instead of delegating to superclass
190
+ it "should allow a name setting to be overriden" do
191
+ Settings.name.should == 'test'
192
+ end
193
+
194
+ it "should allow symbolize_keys" do
195
+ Settings.reload!
196
+ result = Settings.language.haskell.symbolize_keys
197
+ result.class.should == Hash
198
+ result.should == {:paradigm => "functional"}
199
+ end
200
+
201
+ it "should allow symbolize_keys on nested hashes" do
202
+ Settings.reload!
203
+ result = Settings.language.symbolize_keys
204
+ result.class.should == Hash
205
+ result.should == {
206
+ :haskell => {:paradigm => "functional"},
207
+ :smalltalk => {:paradigm => "object oriented"}
208
+ }
209
+ end
210
+
211
+ it "should handle empty file" do
212
+ SettingsEmpty.keys.should eql([])
213
+ end
214
+
215
+ # Put this test last or else call to .instance will load @instance,
216
+ # masking bugs.
217
+ it "should be a hash" do
218
+ Settings.send(:instance).should be_is_a(Hash)
219
+ end
220
+
221
+ describe "#to_hash" do
222
+ it "should return a new instance of a Hash object" do
223
+ Settings.to_hash.should be_kind_of(Hash)
224
+ Settings.to_hash.class.name.should == "Hash"
225
+ Settings.to_hash.object_id.should_not == Settings.object_id
226
+ end
227
+ end
228
+
229
+ end
@@ -0,0 +1,19 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'rspec'
4
+ require 'settingslogic'
5
+ require 'settings'
6
+ require 'settings2'
7
+ require 'settings3'
8
+ require 'settings4'
9
+ require 'settings5'
10
+ require 'settings6'
11
+ require 'settings_empty'
12
+
13
+ # Needed to test Settings3
14
+ Object.send :define_method, 'collides' do
15
+ 'collision'
16
+ end
17
+
18
+ RSpec.configure do |config|
19
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hetznerza-settingslogic
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.9
5
+ platform: ruby
6
+ authors:
7
+ - Ben Johnson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: A simple and straightforward settings solution that uses an ERB enabled
42
+ YAML file and a singleton design pattern.
43
+ email:
44
+ - bjohnson@binarylogic.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - ".travis.yml"
51
+ - Gemfile
52
+ - Gemfile.lock
53
+ - LICENSE
54
+ - README.rdoc
55
+ - Rakefile
56
+ - lib/settingslogic.rb
57
+ - settingslogic.gemspec
58
+ - spec/settings.rb
59
+ - spec/settings.yml
60
+ - spec/settings2.rb
61
+ - spec/settings3.rb
62
+ - spec/settings4.rb
63
+ - spec/settings5.rb
64
+ - spec/settings6.rb
65
+ - spec/settings_empty.rb
66
+ - spec/settings_empty.yml
67
+ - spec/settingslogic_spec.rb
68
+ - spec/spec_helper.rb
69
+ homepage: http://github.com/hetznerZA/settingslogic
70
+ licenses: []
71
+ metadata: {}
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 2.4.5.1
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: A simple and straightforward settings solution that uses an ERB enabled YAML
92
+ file and a singleton design pattern.
93
+ test_files: []