configue 0.1.1 → 0.1.2

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.
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