lukeredpath-simpleconfig 1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,31 @@
1
+ module SimpleConfig
2
+ module ControllerMixin
3
+
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ base.class_eval do
7
+ include InstanceMethods
8
+ helper_method :config
9
+ end
10
+ end
11
+
12
+ module ClassMethods
13
+
14
+ # Returns the application config.
15
+ def config
16
+ SimpleConfig.for(:application)
17
+ end
18
+
19
+ end
20
+
21
+ module InstanceMethods
22
+
23
+ # Instance-level proxy to class-level +config+ method.
24
+ def config
25
+ self.class.config
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,40 @@
1
+ require 'uri'
2
+
3
+ module SimpleConfig
4
+ module Utilities
5
+ class NetworkHost
6
+ attr_reader :name, :port
7
+
8
+ def initialize(name, port = nil, secure = false)
9
+ @name, @port = name, port
10
+ @secure = secure
11
+ end
12
+
13
+ def secure?
14
+ @secure
15
+ end
16
+
17
+ def self.from_string(host_string)
18
+ host, port = host_string.split(':')
19
+ new(host, port.to_i)
20
+ end
21
+
22
+ def to_uri(uri_options = {})
23
+ options = uri_options.except(:host, :port)
24
+ URI::Generic.build(options.reverse_merge(:host => name, :port => port, :scheme => default_uri_scheme))
25
+ end
26
+
27
+ def url_for_path(path)
28
+ to_uri(:path => path).to_s
29
+ end
30
+
31
+ def to_s
32
+ [name, port].compact.join(':')
33
+ end
34
+
35
+ def default_uri_scheme
36
+ secure? ? 'https' : 'http'
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,148 @@
1
+ require 'yaml'
2
+
3
+ module SimpleConfig
4
+
5
+ class << self
6
+ def for(config_name, &block)
7
+ default_manager.for(config_name, &block)
8
+ end
9
+
10
+ def default_manager
11
+ @default_manager ||= Manager.new
12
+ end
13
+ end
14
+
15
+ class Manager
16
+ def initialize
17
+ @configs = {}
18
+ end
19
+
20
+ def for(config_name, &block)
21
+ returning @configs[config_name] ||= Config.new do |config|
22
+ config.configure(&block) if block_given?
23
+ end
24
+ end
25
+ end
26
+
27
+ class Config
28
+ def initialize
29
+ @groups = {}
30
+ @settings = {}
31
+ end
32
+
33
+ def configure(&block)
34
+ instance_eval(&block)
35
+ end
36
+
37
+ def group(name, &block)
38
+ returning @groups[name] ||= Config.new do |group|
39
+ group.configure(&block) if block_given?
40
+ end
41
+ end
42
+
43
+ def set(key, value)
44
+ @settings[key] = value
45
+ end
46
+
47
+ def get(key)
48
+ @settings[key]
49
+ end
50
+
51
+ #
52
+ # Unsets any variable with given +key+
53
+ # and returns variable value if it exists, nil otherwise.
54
+ # Any successive call to exists? :key will return false.
55
+ #
56
+ # exists? :bar # => false
57
+ #
58
+ # set :bar, 'foo'
59
+ # exists? :bar # => true
60
+ #
61
+ # unset :bar # => 'foo'
62
+ # exists? :bar # => false
63
+ #
64
+ def unset(key)
65
+ @settings.delete(key)
66
+ end
67
+
68
+ #
69
+ # Returns whether a variable with given +key+ is set.
70
+ #
71
+ # Please note that this method doesn't care about variable value.
72
+ # A nil variable is considered as set.
73
+ #
74
+ # exists? :bar # => false
75
+ #
76
+ # set :bar, 'foo'
77
+ # exists? :bar # => true
78
+ #
79
+ # set :bar, nil
80
+ # exists? :bar # => true
81
+ #
82
+ # Use unset to completely remove a variable from the collection.
83
+ #
84
+ # set :bar, 'foo'
85
+ # exists? :bar # => true
86
+ #
87
+ # unset :bar
88
+ # exists? :bar # => false
89
+ #
90
+ def exists?(key)
91
+ @settings.key?(key)
92
+ end
93
+
94
+ def load(external_config_file, options={})
95
+ options.reverse_merge!(:if_exists? => false)
96
+
97
+ if options[:if_exists?]
98
+ return unless File.exist?(external_config_file)
99
+ end
100
+
101
+ case File.extname(external_config_file)
102
+ when /rb/
103
+ instance_eval(File.read(external_config_file))
104
+ when /yml|yaml/
105
+ YAMLParser.parse_contents_of_file(external_config_file).parse_into(self)
106
+ end
107
+ end
108
+
109
+ private
110
+ def method_missing(method_name, *args)
111
+ case true
112
+ when @groups.key?(method_name)
113
+ return @groups[method_name]
114
+ when @settings.key?(method_name)
115
+ return get(method_name)
116
+ else
117
+ super(method_name, *args)
118
+ end
119
+ end
120
+ end
121
+
122
+ class YAMLParser
123
+ def initialize(raw_yaml_data)
124
+ @data = YAML.load(raw_yaml_data)
125
+ end
126
+
127
+ def self.parse_contents_of_file(yaml_file)
128
+ new(File.read(yaml_file))
129
+ end
130
+
131
+ def parse_into(config)
132
+ @data.each do |key, value|
133
+ parse(key, value, config)
134
+ end
135
+ end
136
+
137
+ private
138
+ def parse(key, value, config)
139
+ if value.is_a?(Hash)
140
+ group = config.group(key.to_sym)
141
+ value.each { |key, value| parse(key, value, group) }
142
+ else
143
+ config.set(key.to_sym, value)
144
+ end
145
+ end
146
+ end
147
+
148
+ end
@@ -0,0 +1,38 @@
1
+ require File.join(File.dirname(__FILE__), *%w[test_helper])
2
+
3
+ require 'simple_config'
4
+ require 'controller_mixin'
5
+
6
+ class RailsController
7
+ class << self
8
+ attr_reader :helper_methods
9
+ def helper_method(name)
10
+ (@helper_methods ||= []) << name
11
+ end
12
+ end
13
+ end
14
+
15
+ class ControllerMixinTest < Test::Unit::TestCase
16
+
17
+ def setup
18
+ @app_config = SimpleConfig.for(:application) do
19
+ end
20
+
21
+ @controller_klass = Class.new(RailsController)
22
+ end
23
+
24
+ def test_should_define_a_config_class_method_that_returns_the_application_config_when_included
25
+ @controller_klass.send(:include, SimpleConfig::ControllerMixin)
26
+ assert_equal @app_config, @controller_klass.config
27
+ end
28
+
29
+ def test_should_define_a_config_instance_method_that_returns_the_application_config_when_included
30
+ @controller_klass.send(:include, SimpleConfig::ControllerMixin)
31
+ assert_equal @app_config, @controller_klass.new.config
32
+ end
33
+
34
+ def test_should_define_the_config_method_as_helper_method_to_make_it_available_to_views_when_included
35
+ @controller_klass.send(:include, SimpleConfig::ControllerMixin)
36
+ assert_equal [:config], @controller_klass.helper_methods
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ require File.join(File.dirname(__FILE__), *%w[test_helper])
2
+
3
+ require 'simple_config/utilities'
4
+
5
+ class NetworkHostTest < Test::Unit::TestCase
6
+ include SimpleConfig::Utilities
7
+
8
+ def test_should_default_to_no_port
9
+ host = NetworkHost.new('www.example.com')
10
+ assert_nil host.port
11
+ end
12
+
13
+ def test_should_build_a_uri_object_with_the_specified_hostname_and_port_and_a_http_scheme
14
+ uri = NetworkHost.new('www.example.com', 9000).to_uri
15
+ assert_instance_of URI::Generic, uri
16
+ assert_equal 'http', uri.scheme
17
+ end
18
+
19
+ def test_should_build_a_uri_object_with_an_https_scheme_if_secure
20
+ uri = NetworkHost.new('www.example.com', 443, secure = true).to_uri
21
+ assert_equal 'https', uri.scheme
22
+ end
23
+
24
+ def test_should_return_a_url_for_a_given_path
25
+ host = NetworkHost.new('www.example.com')
26
+ assert_equal 'http://www.example.com/foo/bar', host.url_for_path('/foo/bar')
27
+ end
28
+
29
+ def test_should_return_a_string_representation
30
+ assert_equal 'www.example.com:9000', NetworkHost.new('www.example.com', 9000).to_s
31
+ end
32
+
33
+ def test_should_be_constructed_from_a_string_representation
34
+ host = NetworkHost.from_string('www.example.com:9000')
35
+ assert_equal 'www.example.com', host.name
36
+ assert_equal 9000, host.port
37
+ end
38
+ end
@@ -0,0 +1,100 @@
1
+ require File.join(File.dirname(__FILE__), *%w[test_helper])
2
+
3
+ require 'simple_config'
4
+
5
+ class SimpleConfigFunctionalTest < Test::Unit::TestCase
6
+
7
+ def test_simple_config_with_top_level_settings
8
+ config = SimpleConfig.for(:my_test) do
9
+ set :var_one, 'foo'
10
+ set :var_two, 'bar'
11
+ end
12
+
13
+ assert_equal 'foo', config.var_one
14
+ assert_equal 'bar', config.var_two
15
+ end
16
+
17
+ def test_config_with_groups
18
+ config = SimpleConfig.for(:my_test) do
19
+ group :test_group do
20
+ set :var_one, 'foo'
21
+ end
22
+ end
23
+
24
+ assert_equal 'foo', config.test_group.var_one
25
+ end
26
+
27
+ def test_config_with_top_level_settings_and_groups
28
+ config = SimpleConfig.for(:my_test) do
29
+ group :test_group do
30
+ set :var_one, 'foo'
31
+ end
32
+
33
+ set :var_two, 'bar'
34
+ end
35
+
36
+ assert_equal 'foo', config.test_group.var_one
37
+ assert_equal 'bar', config.var_two
38
+ end
39
+
40
+ def test_config_with_nested_groups
41
+ config = SimpleConfig.for(:my_test) do
42
+ group :test_group do
43
+ group :inner_group do
44
+ set :var_one, 'foo'
45
+ end
46
+ end
47
+ end
48
+
49
+ assert_equal 'foo', config.test_group.inner_group.var_one
50
+ end
51
+
52
+ def test_config_with_externally_loaded_ruby_config
53
+ sample_file = File.join(File.dirname(__FILE__), *%w[example.rb])
54
+ File.open(sample_file, "w") do |io|
55
+ io << %(
56
+ set :foo, 'bar'
57
+ )
58
+ end
59
+
60
+ config = SimpleConfig.for(:my_test) do
61
+ load sample_file
62
+ end
63
+
64
+ assert_equal 'bar', config.foo
65
+
66
+ FileUtils.rm_f(sample_file)
67
+ end
68
+
69
+ def test_config_with_externally_loaded_yaml_config
70
+ sample_file = File.join(File.dirname(__FILE__), *%w[example.yml])
71
+ File.open(sample_file, "w") do |io|
72
+ io << %(
73
+ example:
74
+ foo: bar
75
+ baz: qux
76
+
77
+ test: foo
78
+ )
79
+ end
80
+
81
+ config = SimpleConfig.for(:my_test) do
82
+ load sample_file
83
+ end
84
+
85
+ assert_equal 'foo', config.test
86
+ assert_equal 'bar', config.example.foo
87
+ assert_equal 'qux', config.example.baz
88
+
89
+ FileUtils.rm_f(sample_file)
90
+ end
91
+
92
+ def test_config_with_optional_external_config
93
+ assert_nothing_raised do
94
+ SimpleConfig.for(:my_test) do
95
+ load "non_existent_file", :if_exists? => true
96
+ end
97
+ end
98
+ end
99
+
100
+ end
@@ -0,0 +1,108 @@
1
+ require File.join(File.dirname(__FILE__), *%w[test_helper])
2
+
3
+ require 'simple_config'
4
+
5
+ class SimpleConfigConfigTest < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @config = SimpleConfig::Config.new
9
+ end
10
+
11
+ def test_should_be_able_to_set_config_values
12
+ @config.set(:var_one, 'hello world')
13
+ assert_equal 'hello world', @config.get(:var_one)
14
+ end
15
+
16
+ def test_should_be_able_to_access_settings_using_method_access
17
+ @config.set(:foo, 'bar')
18
+ assert_equal 'bar', @config.foo
19
+ end
20
+
21
+ def test_should_raise_NoMethodError_if_setting_does_not_exist_when_using_method_access
22
+ assert_raises(NoMethodError) { @config.some_non_existent_variable }
23
+ end
24
+
25
+ def test_should_return_nil_if_setting_does_not_exist_when_using_get
26
+ assert_nil @config.get(:some_non_existent_variable)
27
+ end
28
+
29
+ def test_unset_should_delete_config_values
30
+ @config.set(:foo, 'bar')
31
+ assert_equal('bar', @config.foo)
32
+ @config.unset(:foo)
33
+ assert_raises(NoMethodError) { @config.foo }
34
+ end
35
+
36
+ def test_unset_should_return_deleted_value
37
+ @config.set(:foo, 'bar')
38
+ assert_equal('bar', @config.unset(:foo))
39
+ end
40
+
41
+ def test_exists_should_return_whether_variable_isset
42
+ assert(!@config.exists?(:foo))
43
+ @config.set(:foo, 'bar')
44
+ assert(@config.exists?(:foo))
45
+ @config.unset(:foo)
46
+ assert(!@config.exists?(:foo))
47
+ end
48
+
49
+ def test_exists_should_consider_empty_values_as_set
50
+ [nil, 0, ''].each do |empty_value|
51
+ @config.set(:foo, empty_value)
52
+ assert_equal(empty_value, @config.get(:foo))
53
+ assert(@config.exists?(:foo))
54
+ end
55
+ end
56
+
57
+ def test_should_return_a_new_group_as_a_separate_config
58
+ group = @config.group(:test)
59
+ assert_instance_of(SimpleConfig::Config, group)
60
+ assert_not_equal @config, group
61
+ end
62
+
63
+ def test_should_return_an_existing_group
64
+ group = @config.group(:test)
65
+ assert_equal group, @config.group(:test)
66
+ end
67
+
68
+ def test_should_configure_group_with_supplied_block_when_given
69
+ group = @config.group(:test) do
70
+ set :group_var, 'value'
71
+ end
72
+ assert_equal 'value', group.group_var
73
+ end
74
+
75
+ def test_should_load_and_parse_external_config_as_ruby_in_context_of_config_instance
76
+ File.stubs(:read).with('external_config.rb').returns(ruby_code = stub('ruby'))
77
+ @config.expects(:instance_eval).with(ruby_code)
78
+ @config.load('external_config.rb')
79
+ end
80
+
81
+ def test_should_laod_and_parse_external_config_as_yaml_in_context_of_config_instance
82
+ parser = stub('YAMLParser')
83
+ SimpleConfig::YAMLParser.stubs(:parse_contents_of_file).with('external_config.yml').returns(parser)
84
+ parser.expects(:parse_into).with(@config)
85
+ @config.load('external_config.yml')
86
+ end
87
+
88
+ def test_should_load_and_parse_external_config_as_yaml_if_config_file_has_full_yaml_extension
89
+ parser = stub('YAMLParser')
90
+ SimpleConfig::YAMLParser.expects(:parse_contents_of_file).with('external_config.yaml').returns(parser)
91
+ parser.stubs(:parse_into)
92
+ @config.load('external_config.yaml')
93
+ end
94
+
95
+ def test_should_load_and_parse_external_config_if_file_exists_when_if_exists_is_true
96
+ File.stubs(:read).with('external_config.rb').returns(ruby_code = stub('ruby'))
97
+ @config.expects(:instance_eval).with(ruby_code)
98
+ File.stubs(:exist?).with('external_config.rb').returns(true)
99
+ @config.load('external_config.rb', :if_exists? => true)
100
+ end
101
+
102
+ def test_should_not_load_and_parse_external_config_if_file_does_not_exist_when_if_exists_is_true
103
+ @config.expects(:instance_eval).never
104
+ File.stubs(:exist?).with('external_config.rb').returns(false)
105
+ @config.load('external_config.rb', :if_exists? => true)
106
+ end
107
+
108
+ end
@@ -0,0 +1,58 @@
1
+ require File.join(File.dirname(__FILE__), *%w[test_helper])
2
+
3
+ require 'simple_config'
4
+
5
+ class YAMLParserTest < Test::Unit::TestCase
6
+ include SimpleConfig
7
+
8
+ def setup
9
+ @config = Config.new
10
+ end
11
+
12
+ def test_parsing_of_a_single_variable
13
+ parser = YAMLParser.new({'foo' => 'bar'}.to_yaml)
14
+ parser.parse_into(@config)
15
+
16
+ assert_equal 'bar', @config.foo
17
+ end
18
+
19
+ def test_parsing_of_multiple_variables
20
+ parser = YAMLParser.new({'foo' => 'bar', 'baz' => 'qux'}.to_yaml)
21
+ parser.parse_into(@config)
22
+
23
+ assert_equal 'bar', @config.foo
24
+ assert_equal 'qux', @config.baz
25
+ end
26
+
27
+ def test_parsing_of_a_group_with_one_variable
28
+ parser = YAMLParser.new({'group1' => {'foo' => 'bar'}}.to_yaml)
29
+ parser.parse_into(@config)
30
+
31
+ assert_equal 'bar', @config.group1.foo
32
+ end
33
+
34
+ def test_parsing_of_a_group_with_two_variables
35
+ parser = YAMLParser.new({'group1' => {'foo' => 'bar', 'baz' => 'qux'}}.to_yaml)
36
+ parser.parse_into(@config)
37
+
38
+ assert_equal 'bar', @config.group1.foo
39
+ assert_equal 'qux', @config.group1.baz
40
+ end
41
+
42
+ def test_parsing_of_a_nested_group
43
+ parser = YAMLParser.new({'group1' => {'group2' => {'foo' => 'bar'}}}.to_yaml)
44
+ parser.parse_into(@config)
45
+
46
+ assert_equal 'bar', @config.group1.group2.foo
47
+ end
48
+ end
49
+
50
+ class YAMLParserFromContentsOfFile < Test::Unit::TestCase
51
+ include SimpleConfig
52
+
53
+ def test_should_initialize_new_parser_from_contents_of_given_file
54
+ File.stubs(:read).with('config.yml').returns(yaml_data = stub('yaml data'))
55
+ YAMLParser.expects(:new).with(yaml_data).returns(parser = stub('YAMLParser'))
56
+ assert_equal parser, YAMLParser.parse_contents_of_file('config.yml')
57
+ end
58
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lukeredpath-simpleconfig
3
+ version: !ruby/object:Gem::Version
4
+ version: "1.0"
5
+ platform: ruby
6
+ authors:
7
+ - Luke Redpath
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-12-05 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Simple Config is a plugin designed to make application-wide configuration settings (e.g. in a Rails app) easy to set and access in an object-oriented fashion.
17
+ email: contact@lukeredpath.co.uk
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/simple_config.rb
26
+ - lib/controller_mixin.rb
27
+ - lib/simple_config/utilities.rb
28
+ has_rdoc: false
29
+ homepage: http://github.com/lukeredpath/simpleconfig
30
+ post_install_message:
31
+ rdoc_options: []
32
+
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: "0"
40
+ version:
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ requirements: []
48
+
49
+ rubyforge_project:
50
+ rubygems_version: 1.2.0
51
+ signing_key:
52
+ specification_version: 2
53
+ summary: Simple object-oriented application settings
54
+ test_files:
55
+ - test/controller_mixin_test.rb
56
+ - test/network_host_test.rb
57
+ - test/simple_config_functional_test.rb
58
+ - test/simple_config_test.rb
59
+ - test/yaml_parser_test.rb