configue 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +15 -13
  4. data/configue.gemspec +1 -1
  5. data/lib/configue.rb +1 -1
  6. data/lib/configue/container.rb +55 -13
  7. data/lib/configue/container_adapter.rb +33 -0
  8. data/lib/configue/criteria.rb +2 -2
  9. data/lib/configue/merger.rb +22 -0
  10. data/lib/configue/node.rb +48 -0
  11. data/lib/configue/setting.rb +34 -31
  12. data/lib/configue/source_loader.rb +44 -0
  13. data/spec/{configue/basic_spec.rb → basic_spec.rb} +19 -3
  14. data/spec/config_spec.rb +20 -0
  15. data/spec/configue/merger_spec.rb +114 -0
  16. data/spec/{configue/namespace_spec.rb → namespace_spec.rb} +3 -3
  17. data/spec/{base_namespace_conf.rb → samples/base_namespace_conf.rb} +0 -0
  18. data/spec/samples/config/admin.yml +6 -0
  19. data/spec/samples/config/test.yml +6 -0
  20. data/spec/samples/config_conf.rb +6 -0
  21. data/spec/{multiple_yaml → samples/multiple_yaml}/foo/baa.yml +0 -0
  22. data/spec/{multiple_yaml → samples/multiple_yaml}/foo/bar/ding.yml +0 -0
  23. data/spec/{multiple_yaml → samples/multiple_yaml}/foo/bar/tick.yml +0 -0
  24. data/spec/{multiple_yaml → samples/multiple_yaml}/foo/pee.yml +0 -0
  25. data/spec/{multiple_yaml_conf.rb → samples/multiple_yaml_conf.rb} +0 -0
  26. data/spec/{namespace → samples/namespace}/base/pee/kaa/conf.yml +0 -0
  27. data/spec/{namespace → samples/namespace}/dev/pee/kaa/conf.yml +0 -0
  28. data/spec/{namespace → samples/namespace}/test/pee/kaa/conf.yml +0 -0
  29. data/spec/{namespace_conf.rb → samples/namespace_conf.rb} +0 -0
  30. data/spec/samples/signs/config.yml +4 -0
  31. data/spec/samples/signs_conf.rb +5 -0
  32. data/spec/samples/single_source_conf.rb +7 -0
  33. data/spec/{single_yaml → samples/single_yaml}/conf.yml +0 -0
  34. data/spec/{single_yaml_conf.rb → samples/single_yaml_conf.rb} +0 -0
  35. data/spec/signs_spec.rb +51 -0
  36. data/spec/support/inner_hash.rb +3 -3
  37. metadata +53 -31
  38. data/lib/configue/inner_hash.rb +0 -53
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b2a6932c57f41d3a8e0face2437eb0ed9c6c9577
4
- data.tar.gz: 4efa8934701bd705a9c79030782465f2a8a93813
3
+ metadata.gz: fe53fc0c3969215bf80141f59536a4027c80009c
4
+ data.tar.gz: 6048c54717f66a3c840cc1f4d6af57cffb488c27
5
5
  SHA512:
6
- metadata.gz: 61a7c799b95237f0278b333a85fb460f17790106940145e22c8a34f3e26fe2a04c5cd62762bac6988a04ec716a06c3da21ed829d5ac747ecb3d8db6afb923674
7
- data.tar.gz: d00f683e0554cde0dd4f43ce81f947a2133f96146d7fe8e6061017190feae6ad6aefd649620dd161b4b5b9856b477727d58e1c59730ada7800f205021155a05e
6
+ metadata.gz: fffd57a26f941018cb692adb873071164c7a7df8f00811da59e1701f273279edd42072ee210be137338bf7e56fc7bf0631bca726918dc17ab29356fab8ef335d
7
+ data.tar.gz: 9588c1c6d5c29df1dea602ad9a66667705d5010bc2e15f27526c08ac495ff908e4cd4204ab37697d24dad832d2ac75799acec104e15b86d49ae5973c7de52968
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2014 hosim <github.hosim@gmail.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.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Configue
2
2
  Configue is a configuration / settings solution that uses YAML files.
3
- It is almost a fork of SettingsLogic.
3
+ It is almost a fork of [SettingsLogic](https://github.com/binarylogic/settingslogic).
4
4
  Configue can read multiple YAML files and you can use big configuration data
5
5
  simply.
6
6
 
@@ -20,30 +20,28 @@ end
20
20
  ### Write your settings in YAML file
21
21
  ```yaml
22
22
  # config/accounts/admin_users.yml
23
- config:
24
- accounts:
25
- admin_users:
26
- - grumpy
27
- - sneezy
23
+ accounts:
24
+ admin_users:
25
+ - grumpy
26
+ - sneezy
28
27
  ```
29
28
 
30
29
  You can make multiple settings files.
31
30
 
32
31
  ```yaml
33
32
  # config/accounts/test_users.yml
34
- config:
35
- accounts:
36
- test_users:
37
- - sleepy
38
- - dopey
33
+ accounts:
34
+ test_users:
35
+ - sleepy
36
+ - dopey
39
37
  ```
40
38
 
41
39
  ### Access your settings
42
40
  ```
43
- >> MyConf.config.accounts.admin_users
41
+ >> MyConf.accounts.admin_users
44
42
  => ["grumpy", "sneezy"]
45
43
 
46
- >> MyConf.config.accounts.test_users
44
+ >> MyConf.accounts.test_users
47
45
  => ["sleepy", "dopey"]
48
46
  ```
49
47
 
@@ -81,7 +79,9 @@ test:
81
79
  - foo
82
80
  - woo
83
81
  ```
82
+
84
83
  and define a class for the settings
84
+
85
85
  ```ruby
86
86
  class MyConf < Configue::Container
87
87
  config.source_dir "#{File.dirname(__FILE__)}/config/settings"
@@ -89,7 +89,9 @@ class MyConf < Configue::Container
89
89
  config.namespace :test
90
90
  end
91
91
  ```
92
+
92
93
  you can access it in the following manner:
94
+
93
95
  ```
94
96
  >> MyConf.foo.baa
95
97
  => ["boo", "foo", "woo"]
data/configue.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
12
12
  s.files = `git ls-files`.split("\n")
13
13
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
14
  s.require_paths = ["lib"]
15
- s.version = "0.1.1"
15
+ s.version = "0.1.2"
16
16
  s.license = "MIT"
17
17
 
18
18
  s.add_development_dependency 'rspec'
data/lib/configue.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
2
  require "configue/setting"
3
+ require "configue/node"
3
4
  require "configue/container"
4
- require "configue/inner_hash"
5
5
 
@@ -1,33 +1,75 @@
1
1
  # coding: utf-8
2
2
 
3
- require "forwardable"
3
+ require "configue/container_adapter"
4
4
  require "configue/criteria"
5
5
 
6
6
  module Configue
7
- class Container
8
- extend Forwardable
9
-
10
- def_delegators :@node, :keys, :key?, :has_key?, :[]
11
-
12
- def initialize(hash)
13
- @node = hash
14
- end
7
+ # +Configue::Container+ is a setting solution using a YAML file.
8
+ #
9
+ # When you have such configuration files:
10
+ #
11
+ # # config/accounts/admin_users.yml
12
+ # accounts:
13
+ # admin_users:
14
+ # - grumpy
15
+ # - sneezy
16
+ #
17
+ # # config/accounts/test_users.yml
18
+ # accounts:
19
+ # test_users:
20
+ # - sleepy
21
+ # - dopey
22
+ #
23
+ # this could be:
24
+ #
25
+ # class Foo < Configue::Container
26
+ # config.source_dir "#{File.dirname(__FILE__)}/config"
27
+ # end
28
+ #
29
+ # Foo.accounts.admin_users
30
+ # # => ["grumpy", "sneezy"]
31
+ #
32
+ # Foo.accounts.test_users
33
+ # # => ["sleepy", "dopey"]
34
+ #
35
+ class Container < Node
15
36
 
37
+ # When you do not know the setting has keys that you want to
38
+ # specify and want to avoid +NoMethodError+, you could use
39
+ # +query+ and +retrieve+.
40
+ #
41
+ # Foo.query("accounts.admin_users").retrieve
42
+ # # => ["grumpy", "sneezy"]
43
+ #
44
+ # Foo.query("users.admin_users").retrieve
45
+ # # => nil
46
+ #
47
+ # Foo.query[:accounts][:admin_users].retrieve
48
+ # # => ["grumpy", "sneezy"]
49
+ #
16
50
  def query(key=nil)
17
- q = Criteria.new(@node)
51
+ q = Criteria.new(self)
18
52
  q = key.split('.').each.inject(q) {|c, k| c[k] } if key
19
53
  q
20
54
  end
21
55
 
22
56
  class << self
57
+ # +config+ allows you to access the object for setting container.
23
58
  def config
24
- @setting ||= Setting.new(self)
59
+ @config_access_name = "config"
60
+ @setting ||= Setting.new(ContainerAdapter.new(self))
61
+ end
62
+
63
+ def config_setting
64
+ @config_access_name = "config_setting"
65
+ @setting ||= Setting.new(ContainerAdapter.new(self))
25
66
  end
26
- alias_method :config_setting, :config
27
67
 
28
68
  private
29
69
  def method_missing(name, *args, &block)
30
- @instance ||= new(@setting.load_source)
70
+ # makes @instance in this line.
71
+ @setting.load!
72
+
31
73
  if @instance.key?(name)
32
74
  @instance[name]
33
75
  else
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+
3
+ module Configue
4
+ class ContainerAdapter
5
+ def initialize(container_class)
6
+ @class = container_class
7
+ end
8
+
9
+ def new_container(hash)
10
+ self.instance = @class.new(hash)
11
+ end
12
+
13
+ def instance
14
+ @class.instance_variable_get(:@instance)
15
+ end
16
+
17
+ def instance=(arg)
18
+ raise TypeError unless arg.respond_to?(:[]) or arg.respond_to?(:keys)
19
+
20
+ @class.instance_variable_set(:@instance, arg)
21
+ sig = class << @class; self; end
22
+ arg.keys.each do |k|
23
+ next unless k.to_s =~ /\A\w[\w0-9]*\z/
24
+ sig.__send__(:define_method, k, -> { arg[k] })
25
+ end
26
+ arg
27
+ end
28
+
29
+ def config_method_name
30
+ @class.instance_variable_get(:@config_access_name)
31
+ end
32
+ end
33
+ end
@@ -13,14 +13,14 @@ module Configue
13
13
 
14
14
  def retrieve
15
15
  @path.each.inject(@hash) do |h, key|
16
- return nil unless h.is_a?(Hash) and h.has_key?(key)
16
+ return nil unless h.respond_to?(:has_key?) and h.has_key?(key)
17
17
  h[key]
18
18
  end
19
19
  end
20
20
 
21
21
  def exist?
22
22
  @path.each.inject(@hash) do |h, key|
23
- return false unless h.is_a?(Hash) and h.has_key?(key)
23
+ return false unless h.respond_to?(:has_key?) and h.has_key?(key)
24
24
  h[key]
25
25
  end
26
26
  true
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+
3
+ module Configue
4
+ module Merger
5
+ def merge(hash1, hash2)
6
+ return hash2 unless hash1
7
+ return hash1 unless hash2
8
+
9
+ merger = ->(key, h1, h2) {
10
+ if h1.is_a?(Hash) and h2.is_a?(Hash)
11
+ h1.merge(h2, &merger)
12
+ else
13
+ h2
14
+ end
15
+ }
16
+
17
+ hash1.merge(hash2, &merger)
18
+ end
19
+
20
+ module_function :merge
21
+ end
22
+ end
@@ -0,0 +1,48 @@
1
+ # coding: utf-8
2
+
3
+ module Configue
4
+ class Node
5
+ def initialize(hash)
6
+ raise TypeError unless hash.respond_to?(:[])
7
+
8
+ sig = class << self; self; end
9
+ @hash = hash.each.inject({}) do |h, (k, v)|
10
+ sig.__send__(:define_method, k, ->{ self[k] })
11
+ h[k.to_s] = v; h
12
+ end
13
+ self
14
+ end
15
+
16
+ def [](key)
17
+ k = key.to_s
18
+ v = @hash[k]
19
+ @hash[k] = self.class.new(v) if v.is_a?(Hash)
20
+ @hash[k]
21
+ end
22
+
23
+ def fetch(key)
24
+ k = key.to_s
25
+ v = @hash[key]
26
+ @hash[k] = self.class.new(v) if v.is_a?(Hash)
27
+ @hash.fetch(k)
28
+ end
29
+
30
+ def key?(key)
31
+ k = key.to_s
32
+ @hash.key?(k)
33
+ end
34
+ alias_method :has_key?, :key?
35
+
36
+ def keys
37
+ @hash.keys
38
+ end
39
+
40
+ def to_hash
41
+ @hash.dup
42
+ end
43
+
44
+ def to_s
45
+ @hash.to_s
46
+ end
47
+ end
48
+ end
@@ -1,11 +1,13 @@
1
1
  # coding: utf-8
2
2
 
3
+ require "configue/merger"
4
+ require "configue/source_loader"
3
5
  require "configue/yaml_loader"
4
6
 
5
7
  module Configue
6
8
  class Setting
7
9
  def initialize(owner_class)
8
- @owner_class = owner_class
10
+ @owner = owner_class
9
11
  @loader = YamlLoader.new
10
12
  end
11
13
 
@@ -28,9 +30,9 @@ module Configue
28
30
  end
29
31
 
30
32
  def source_dir(*dirs)
31
- @source_dirs ||= []
32
- @source_dirs += dirs unless dirs.empty?
33
- @source_dirs
33
+ @sources ||= []
34
+ @sources += dirs.map {|d| {dir: d}} unless dirs.empty?
35
+ @sources
34
36
  end
35
37
 
36
38
  def source_dir=(dir)
@@ -41,42 +43,43 @@ module Configue
41
43
  end
42
44
  end
43
45
 
44
- def load_source
45
- hash = load_sources
46
+ def source_file(*files)
47
+ @sources ||= []
48
+ @sources += files.map {|f| {file: f}} unless files.empty?
49
+ @sources
50
+ end
46
51
 
47
- space = namespace.to_s
48
- unless space.empty?
49
- base = base_namespace.to_s
50
- result = InnerHash.new
51
- result.deep_merge!(hash[base]) if base_namespace
52
- result.deep_merge!(hash[space]) if hash[space]
53
- hash = result
54
- end
55
- hash
52
+ def load!
53
+ @owner.instance ? @owner.instance : @owner.new_container(load_sources)
56
54
  end
57
55
 
58
56
  private
59
57
  def load_sources
60
- @source_dirs.each.inject(InnerHash.new) do |root, dir|
61
- Dir.glob("#{dir}/**/*.#{@loader.extention}") do |path|
62
- source = @loader.load(path)
63
- if namespace and source[namespace.to_s]
64
- namespaced_hash(root, source)
65
- else
66
- root.deep_merge!(source)
67
- end
68
- end
69
- root
70
- end
58
+ loader = SourceLoader.new(@loader, @sources, @namespace, @base_namespace)
59
+ hash = loader.load
60
+ hash = namespaced_hash(hash) if namespace
61
+ hash
71
62
  end
72
63
 
73
- def namespaced_hash(root, hash)
74
- base = base_namespace.to_s
64
+ def namespaced_hash(hash)
75
65
  space = namespace.to_s
66
+ base = base_namespace.to_s
67
+ result = {}
68
+ result = Merger.merge(result, hash[base]) if base_namespace
69
+ result = Merger.merge(result, hash[space]) if hash.key?(space)
70
+ result
71
+ end
76
72
 
77
- root.deep_merge!(base => hash[base]) if ! base.empty? and hash[base]
78
- root.deep_merge!(space => hash[space])
79
- root
73
+ def method_missing(name, *args, &block)
74
+ access_name = @owner.config_method_name
75
+ return super unless access_name
76
+
77
+ instance = self.load!
78
+ if instance[access_name]
79
+ instance[access_name].__send__(name, *args, &block)
80
+ else
81
+ super
82
+ end
80
83
  end
81
84
  end
82
85
  end
@@ -0,0 +1,44 @@
1
+ # coding: utf-8
2
+
3
+ require "configue/merger"
4
+
5
+ module Configue
6
+ class SourceLoader
7
+ def initialize(loader, sources, namespace=nil, base_namespace=nil)
8
+ @loader = loader
9
+ @sources = sources
10
+ @namespace = namespace.to_s if namespace
11
+ @basespace = base_namespace.to_s if base_namespace
12
+ end
13
+
14
+ def load
15
+ @sources.each do |src|
16
+ src.each {|k, v| __send__("load_#{k}", v) }
17
+ end
18
+ @hash
19
+ end
20
+
21
+ protected
22
+ def load_dir(dir)
23
+ Dir.glob("#{dir}/**/*.#{@loader.extention}") do |file|
24
+ load_file(file)
25
+ end
26
+ end
27
+
28
+ def load_file(file)
29
+ source = @loader.load(file)
30
+ if @namespace and source[@namespace]
31
+ namespaced_hash(source)
32
+ else
33
+ @hash = Merger.merge(@hash, source)
34
+ end
35
+ end
36
+
37
+ def namespaced_hash(hash)
38
+ if @basespace and hash.key?(@basespace)
39
+ @hash = Merger.merge(@hash, @basespace => hash[@basespace])
40
+ end
41
+ @hash = Merger.merge(@hash, @namespace => hash[@namespace])
42
+ end
43
+ end
44
+ end
@@ -1,9 +1,9 @@
1
1
  # coding: utf-8
2
- require File.expand_path("../../spec_helper", __FILE__)
2
+ require File.expand_path("../spec_helper", __FILE__)
3
3
 
4
4
  describe "Configue::Container" do
5
5
  context "when reading a single yaml file" do
6
- require "#{File.dirname(__FILE__)}/../single_yaml_conf"
6
+ require File.expand_path("../samples/single_yaml_conf", __FILE__)
7
7
 
8
8
  context "1st level" do
9
9
  it_should_behave_like "an InnerHash instance",
@@ -22,7 +22,7 @@ describe "Configue::Container" do
22
22
  end
23
23
 
24
24
  context "when reading multiple yaml files" do
25
- require "#{File.dirname(__FILE__)}/../multiple_yaml_conf"
25
+ require File.expand_path("../samples/multiple_yaml_conf", __FILE__)
26
26
 
27
27
  context "1st level" do
28
28
  it_should_behave_like "an InnerHash instance",
@@ -46,4 +46,20 @@ describe "Configue::Container" do
46
46
  {"ding" => ["dong", "dang"], "tick" => ["tack", "toe"]}
47
47
  end
48
48
  end
49
+
50
+ context "when reading a single yaml with source_file" do
51
+ require File.expand_path("../samples/single_source_conf", __FILE__)
52
+
53
+ context "1st level" do
54
+ it_should_behave_like "an InnerHash instance",
55
+ SingleSourceConf,
56
+ {"config" => ["accounts"]}
57
+ end
58
+
59
+ context "2nd level" do
60
+ it_should_behave_like "an InnerHash instance",
61
+ SingleSourceConf["config"],
62
+ {"accounts" => ["admin_users"]}
63
+ end
64
+ end
49
65
  end
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+ require File.expand_path("../spec_helper", __FILE__)
3
+
4
+ describe "Configue::Container" do
5
+ context "when a top key is 'config' in the setting files" do
6
+ require File.expand_path("../samples/config_conf", __FILE__)
7
+
8
+ context "1st level" do
9
+ it_should_behave_like "an InnerHash instance",
10
+ ConfigConf,
11
+ {"config" => ["accounts"]}
12
+ end
13
+
14
+ context "2nd level" do
15
+ it_should_behave_like "an InnerHash instance",
16
+ ConfigConf["config"],
17
+ {"accounts" => ["admin_users", "test_users"]}
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,114 @@
1
+ # coding: utf-8
2
+ require File.expand_path("../../spec_helper", __FILE__)
3
+
4
+ describe Configue::Merger do
5
+ describe ".merge" do
6
+ context "when merging a hash with another hash" do
7
+ let(:former) do
8
+ {
9
+ a: {
10
+ aa: {
11
+ aaa: 1,
12
+ aab: 2,
13
+ },
14
+ ab: {
15
+ aba: 1,
16
+ abb: 2,
17
+ },
18
+ },
19
+ }
20
+ end
21
+
22
+ let(:latter) do
23
+ {
24
+ a: {
25
+ aa: {
26
+ aac: 3,
27
+ },
28
+ ab: {
29
+ abc: 3,
30
+ },
31
+ },
32
+ b: {
33
+ ba: {
34
+ baa: 1,
35
+ },
36
+ },
37
+ }
38
+ end
39
+
40
+ let(:expected) do
41
+ {
42
+ a: {
43
+ aa: {
44
+ aaa: 1,
45
+ aab: 2,
46
+ aac: 3,
47
+ },
48
+ ab: {
49
+ aba: 1,
50
+ abb: 2,
51
+ abc: 3,
52
+ },
53
+ },
54
+ b: {
55
+ ba: {
56
+ baa: 1,
57
+ },
58
+ },
59
+ }
60
+ end
61
+
62
+ it "returns a merged hash" do
63
+ actual = Configue::Merger.merge(former, latter)
64
+ expect(actual).to eq expected
65
+ end
66
+ end
67
+
68
+ context "when the latter is nil" do
69
+ let(:former) do
70
+ {
71
+ a: {
72
+ aa: 1,
73
+ },
74
+ }
75
+ end
76
+
77
+ let(:expected) do
78
+ {
79
+ a: {
80
+ aa: 1,
81
+ },
82
+ }
83
+ end
84
+
85
+ it "returns the former hash remaining without change" do
86
+ actual = Configue::Merger.merge(former, nil)
87
+ expect(actual).to eq expected
88
+ end
89
+ end
90
+
91
+ context "when the former is nil" do
92
+ let(:latter) do
93
+ {
94
+ a: {
95
+ aa: 9,
96
+ },
97
+ }
98
+ end
99
+
100
+ let(:expected) do
101
+ {
102
+ a: {
103
+ aa: 9,
104
+ },
105
+ }
106
+ end
107
+
108
+ it "returns the latter remaining without change" do
109
+ actual = Configue::Merger.merge(nil, latter)
110
+ expect(actual).to eq expected
111
+ end
112
+ end
113
+ end
114
+ end
@@ -1,9 +1,9 @@
1
1
  # coding: utf-8
2
- require File.expand_path("../../spec_helper", __FILE__)
2
+ require File.expand_path("../spec_helper", __FILE__)
3
3
 
4
4
  describe "Configue::Container" do
5
5
  context "when specifing 'namespace'" do
6
- require "#{File.dirname(__FILE__)}/../namespace_conf"
6
+ require File.expand_path("../samples/namespace_conf", __FILE__)
7
7
 
8
8
  context "1st level" do
9
9
  it_should_behave_like "an InnerHash instance",
@@ -25,7 +25,7 @@ describe "Configue::Container" do
25
25
  end
26
26
 
27
27
  context "when specifing 'namespace' and 'base_namespace'" do
28
- require "#{File.dirname(__FILE__)}/../base_namespace_conf"
28
+ require File.expand_path("../samples/base_namespace_conf", __FILE__)
29
29
 
30
30
  context "1st level" do
31
31
  it_should_behave_like "an InnerHash instance",
@@ -0,0 +1,6 @@
1
+ config:
2
+ accounts:
3
+ admin_users:
4
+ - grumpy
5
+ - sneezy
6
+
@@ -0,0 +1,6 @@
1
+ config:
2
+ accounts:
3
+ test_users:
4
+ - sleepy
5
+ - dopey
6
+
@@ -0,0 +1,6 @@
1
+ # coding: utf-8
2
+
3
+ class ConfigConf < Configue::Container
4
+ config.source_dir "#{File.dirname(__FILE__)}/config"
5
+ config.load!
6
+ end
@@ -0,0 +1,4 @@
1
+ "a top key with some spaces":
2
+ "a key with some spaces": OK
3
+ "!@#$%^&*()_+":
4
+ "+_)(*&^%$#@!": OK
@@ -0,0 +1,5 @@
1
+ # coding: utf-8
2
+
3
+ class SignsConf < Configue::Container
4
+ config.source_dir "#{File.dirname(__FILE__)}/signs"
5
+ end
@@ -0,0 +1,7 @@
1
+ # coding: utf-8
2
+ require "configue"
3
+
4
+ class SingleSourceConf < Configue::Container
5
+ config.source_file "#{File.dirname(__FILE__)}/config/admin.yml"
6
+ config.load!
7
+ end
File without changes
@@ -0,0 +1,51 @@
1
+ # coding: utf-8
2
+ require File.expand_path("../spec_helper", __FILE__)
3
+
4
+ describe "Configue::Container" do
5
+ context "when reading a yaml file with keys included signs" do
6
+ require File.expand_path("../samples/signs_conf", __FILE__)
7
+
8
+ context "1st level" do
9
+ describe ".keys" do
10
+ it "returns keys described in the setting file" do
11
+ actual = SignsConf.keys
12
+ expect(actual).to match_array(["a top key with some spaces", "!@#$%^&*()_+"])
13
+ end
14
+ end
15
+
16
+ describe ".[]" do
17
+ it "returns a value associated with the parameter" do
18
+ actual = SignsConf["a top key with some spaces"].to_hash
19
+ expected = {"a key with some spaces" => "OK"}
20
+ expect(actual).to eq expected
21
+
22
+ actual = SignsConf["!@#$%^&*()_+"].to_hash
23
+ expected = {"+_)(*&^%$#@!" => "OK"}
24
+ expect(actual).to eq expected
25
+ end
26
+ end
27
+ end
28
+
29
+ context "2nd level" do
30
+ describe ".keys" do
31
+ it "returns keys described in the setting file" do
32
+ actual = SignsConf["a top key with some spaces"].keys
33
+ expect(actual).to match_array(["a key with some spaces"])
34
+
35
+ actual = SignsConf["!@#$%^&*()_+"].keys
36
+ expect(actual).to match_array(["+_)(*&^%$#@!"])
37
+ end
38
+ end
39
+
40
+ describe ".[]" do
41
+ it "returns a value associated with the parameter" do
42
+ actual = SignsConf["a top key with some spaces"]["a key with some spaces"]
43
+ expect(actual).to eq "OK"
44
+
45
+ actual = SignsConf["!@#$%^&*()_+"]["+_)(*&^%$#@!"]
46
+ expect(actual).to eq "OK"
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -39,7 +39,7 @@ shared_examples_for "an InnerHash instance" do |object, hash|
39
39
  context "when specifing the existing key names" do
40
40
  it "returns a Hash value" do
41
41
  hash.each do |key, value|
42
- expect(object[key]).to be_a(Hash) if value
42
+ expect(object[key]).to be_a(Configue::Node) if value
43
43
  end
44
44
  end
45
45
 
@@ -55,7 +55,7 @@ shared_examples_for "an InnerHash instance" do |object, hash|
55
55
  context "when specifing the existing key names in symbol" do
56
56
  it "returns a Hash value" do
57
57
  hash.each do |key, value|
58
- expect(object[key.to_sym]).to be_a(Hash) if value
58
+ expect(object[key.to_sym]).to be_a(Configue::Node) if value
59
59
  end
60
60
  end
61
61
 
@@ -73,7 +73,7 @@ shared_examples_for "an InnerHash instance" do |object, hash|
73
73
  context "when call methods which names are existing in the setting(s)" do
74
74
  it "returns a Hash value" do
75
75
  hash.each do |key, value|
76
- expect(object.__send__(key)).to be_a(Hash) if value
76
+ expect(object.__send__(key)).to be_a(Configue::Node) if value
77
77
  end
78
78
  end
79
79
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: configue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - hosim
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-21 00:00:00.000000000 Z
11
+ date: 2014-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -32,29 +32,42 @@ extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
34
  - Gemfile
35
+ - MIT-LICENSE
35
36
  - README.md
36
37
  - Rakefile
37
38
  - configue.gemspec
38
39
  - lib/configue.rb
39
40
  - lib/configue/container.rb
41
+ - lib/configue/container_adapter.rb
40
42
  - lib/configue/criteria.rb
41
- - lib/configue/inner_hash.rb
43
+ - lib/configue/merger.rb
44
+ - lib/configue/node.rb
42
45
  - lib/configue/setting.rb
46
+ - lib/configue/source_loader.rb
43
47
  - lib/configue/yaml_loader.rb
44
- - spec/base_namespace_conf.rb
45
- - spec/configue/basic_spec.rb
46
- - spec/configue/namespace_spec.rb
47
- - spec/multiple_yaml/foo/baa.yml
48
- - spec/multiple_yaml/foo/bar/ding.yml
49
- - spec/multiple_yaml/foo/bar/tick.yml
50
- - spec/multiple_yaml/foo/pee.yml
51
- - spec/multiple_yaml_conf.rb
52
- - spec/namespace/base/pee/kaa/conf.yml
53
- - spec/namespace/dev/pee/kaa/conf.yml
54
- - spec/namespace/test/pee/kaa/conf.yml
55
- - spec/namespace_conf.rb
56
- - spec/single_yaml/conf.yml
57
- - spec/single_yaml_conf.rb
48
+ - spec/basic_spec.rb
49
+ - spec/config_spec.rb
50
+ - spec/configue/merger_spec.rb
51
+ - spec/namespace_spec.rb
52
+ - spec/samples/base_namespace_conf.rb
53
+ - spec/samples/config/admin.yml
54
+ - spec/samples/config/test.yml
55
+ - spec/samples/config_conf.rb
56
+ - spec/samples/multiple_yaml/foo/baa.yml
57
+ - spec/samples/multiple_yaml/foo/bar/ding.yml
58
+ - spec/samples/multiple_yaml/foo/bar/tick.yml
59
+ - spec/samples/multiple_yaml/foo/pee.yml
60
+ - spec/samples/multiple_yaml_conf.rb
61
+ - spec/samples/namespace/base/pee/kaa/conf.yml
62
+ - spec/samples/namespace/dev/pee/kaa/conf.yml
63
+ - spec/samples/namespace/test/pee/kaa/conf.yml
64
+ - spec/samples/namespace_conf.rb
65
+ - spec/samples/signs/config.yml
66
+ - spec/samples/signs_conf.rb
67
+ - spec/samples/single_source_conf.rb
68
+ - spec/samples/single_yaml/conf.yml
69
+ - spec/samples/single_yaml_conf.rb
70
+ - spec/signs_spec.rb
58
71
  - spec/spec_helper.rb
59
72
  - spec/support/inner_hash.rb
60
73
  homepage: https://github.com/hosim/configue
@@ -82,19 +95,28 @@ signing_key:
82
95
  specification_version: 4
83
96
  summary: A simple configuration solution
84
97
  test_files:
85
- - spec/base_namespace_conf.rb
86
- - spec/configue/basic_spec.rb
87
- - spec/configue/namespace_spec.rb
88
- - spec/multiple_yaml/foo/baa.yml
89
- - spec/multiple_yaml/foo/bar/ding.yml
90
- - spec/multiple_yaml/foo/bar/tick.yml
91
- - spec/multiple_yaml/foo/pee.yml
92
- - spec/multiple_yaml_conf.rb
93
- - spec/namespace/base/pee/kaa/conf.yml
94
- - spec/namespace/dev/pee/kaa/conf.yml
95
- - spec/namespace/test/pee/kaa/conf.yml
96
- - spec/namespace_conf.rb
97
- - spec/single_yaml/conf.yml
98
- - spec/single_yaml_conf.rb
98
+ - spec/basic_spec.rb
99
+ - spec/config_spec.rb
100
+ - spec/configue/merger_spec.rb
101
+ - spec/namespace_spec.rb
102
+ - spec/samples/base_namespace_conf.rb
103
+ - spec/samples/config/admin.yml
104
+ - spec/samples/config/test.yml
105
+ - spec/samples/config_conf.rb
106
+ - spec/samples/multiple_yaml/foo/baa.yml
107
+ - spec/samples/multiple_yaml/foo/bar/ding.yml
108
+ - spec/samples/multiple_yaml/foo/bar/tick.yml
109
+ - spec/samples/multiple_yaml/foo/pee.yml
110
+ - spec/samples/multiple_yaml_conf.rb
111
+ - spec/samples/namespace/base/pee/kaa/conf.yml
112
+ - spec/samples/namespace/dev/pee/kaa/conf.yml
113
+ - spec/samples/namespace/test/pee/kaa/conf.yml
114
+ - spec/samples/namespace_conf.rb
115
+ - spec/samples/signs/config.yml
116
+ - spec/samples/signs_conf.rb
117
+ - spec/samples/single_source_conf.rb
118
+ - spec/samples/single_yaml/conf.yml
119
+ - spec/samples/single_yaml_conf.rb
120
+ - spec/signs_spec.rb
99
121
  - spec/spec_helper.rb
100
122
  - spec/support/inner_hash.rb
@@ -1,53 +0,0 @@
1
- # coding: utf-8
2
-
3
- module Configue
4
- class InnerHash < Hash
5
- def initialize(source_hash=nil)
6
- deep_merge!(source_hash) if source_hash
7
- end
8
-
9
- def deep_merge!(other)
10
- deep_update(other)
11
-
12
- sig = class << self; self; end
13
- other.keys.each do |k|
14
- sig.__send__(:define_method, k, ->{ self[k] })
15
- end
16
- self
17
- end
18
-
19
- def fetch(key, *args); super(key.to_s, *args); end
20
- def delete(key); super(key.to_s); end
21
- def key?(key); super(key.to_s); end
22
- alias_method :has_key?, :key?
23
-
24
- alias_method :_get_value, :[]
25
- alias_method :_set_value, :[]=
26
- private :_get_value
27
- private :_set_value
28
-
29
- def [](key)
30
- value = _get_value(key.to_s)
31
- value = self.class.new(value) if value.is_a? Hash
32
- yield value if block_given?
33
- value
34
- end
35
-
36
- def []=(key, value)
37
- v = value
38
- v = self.class.new(v) if v.is_a? Hash
39
- _set_value(key.to_s, v)
40
- end
41
-
42
- protected
43
- def deep_update(other_hash, &b)
44
- other_hash.each do |k, v|
45
- if v.is_a?(Hash)
46
- v = self.key?(k) ? self[k].deep_update(v) : self.class.new(v)
47
- end
48
- self[k] = v
49
- end
50
- self
51
- end
52
- end
53
- end