config_module 1.2.2 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +23 -0
- data/.codeclimate.yml +1 -0
- data/.gitlab-ci.yml +2 -0
- data/.rubocop.yml +50 -0
- data/.travis.yml +4 -3
- data/Gemfile +22 -12
- data/README.markdown +1 -1
- data/Rakefile +2 -0
- data/config_module.gemspec +18 -16
- data/lib/config_module/config_helper.rb +14 -7
- data/lib/config_module/config_option.rb +55 -15
- data/lib/config_module/exceptions.rb +4 -2
- data/lib/config_module/version.rb +3 -1
- data/lib/config_module.rb +15 -7
- data/uspec/config_helper_spec.rb +6 -4
- data/uspec/config_module_spec.rb +49 -27
- data/uspec/config_option_spec.rb +73 -15
- data/uspec/example_config.rb +5 -3
- data/uspec/exceptions_spec.rb +5 -3
- data/uspec/method_missing_spec.rb +5 -3
- data/uspec/namespace_spec.rb +26 -28
- data/uspec/spec_helper.rb +8 -6
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04d4f6c816e394924d4d3e833ef2d3c8be39cc6048a1167dca507761c6f965db
|
4
|
+
data.tar.gz: b782426dd752d18ed5ca2a8a6ec2f8c98998156d6fd2b5807cea0f7eebf629fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b12be1b132e0e47a3a80f1bde3ae177e1f8ad7f73edd9228ad3c2830e706189571104ae0768b0c5fa53b986f444894dde2b9a6e34a8b1a93b1ddf0ddcd68f32f
|
7
|
+
data.tar.gz: 53678ce655a23c423bad46535a774075a8ecb5483ef9237677d3e0484a5a500884391a11beab622c0d2e1915205cd7530379581d1e5428ed61c23bd14e0bf437
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Ruby CircleCI 2.0 configuration file
|
2
|
+
#
|
3
|
+
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
|
4
|
+
#
|
5
|
+
version: 2
|
6
|
+
jobs:
|
7
|
+
build:
|
8
|
+
docker:
|
9
|
+
# specify the version you desire here
|
10
|
+
- image: circleci/ruby:2.6
|
11
|
+
|
12
|
+
working_directory: ~/repo
|
13
|
+
|
14
|
+
steps:
|
15
|
+
- checkout
|
16
|
+
- run:
|
17
|
+
name: install dependencies
|
18
|
+
command: |
|
19
|
+
bundle install --jobs=4 --retry=3 --path vendor/bundle
|
20
|
+
- run:
|
21
|
+
name: run tests
|
22
|
+
command:
|
23
|
+
bundle exec uspec
|
data/.codeclimate.yml
CHANGED
data/.gitlab-ci.yml
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# Rubocop override settings
|
2
|
+
|
3
|
+
AllCops:
|
4
|
+
TargetRubyVersion: 2.0
|
5
|
+
|
6
|
+
Metrics/LineLength:
|
7
|
+
Max: 120
|
8
|
+
Exclude:
|
9
|
+
- config_module.gemspec
|
10
|
+
- "uspec/**/*"
|
11
|
+
|
12
|
+
Naming/PredicateName:
|
13
|
+
Enabled: false
|
14
|
+
|
15
|
+
Style/PreferredHashMethods:
|
16
|
+
Exclude:
|
17
|
+
- "**/*"
|
18
|
+
|
19
|
+
Style/Documentation:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Style/MethodDefParentheses:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
Style/ParallelAssignment:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
Style/SingleLineMethods:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
Style/Alias:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
Style/CaseEquality:
|
35
|
+
Enabled: false
|
36
|
+
|
37
|
+
Style/SymbolArray:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
Bundler/OrderedGems:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
Style/StringLiterals:
|
44
|
+
EnforcedStyle: double_quotes
|
45
|
+
|
46
|
+
Style/StringLiteralsInInterpolation:
|
47
|
+
EnforcedStyle: double_quotes
|
48
|
+
|
49
|
+
Layout/AccessModifierIndentation:
|
50
|
+
EnforcedStyle: outdent
|
data/.travis.yml
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
+
- 2.6
|
3
4
|
- 2.5
|
4
5
|
- 2.4
|
5
6
|
- 2.3
|
@@ -8,19 +9,19 @@ rvm:
|
|
8
9
|
- 2.0
|
9
10
|
|
10
11
|
- ruby-head
|
11
|
-
- jruby-9.
|
12
|
+
- jruby-9.2.7.0
|
12
13
|
- jruby-21mode
|
13
14
|
|
14
15
|
matrix:
|
15
16
|
allow_failures:
|
16
17
|
- rvm: ruby-head
|
17
|
-
- rvm: jruby-9.
|
18
|
+
- rvm: jruby-9.2.7.0
|
18
19
|
- rvm: jruby-21mode
|
19
20
|
|
20
21
|
sudo: false
|
21
22
|
|
22
23
|
before_install:
|
23
|
-
- gem
|
24
|
+
- which bundle || gem install bundler
|
24
25
|
before_script:
|
25
26
|
- bundle exec gem list
|
26
27
|
script: bundle exec uspec
|
data/Gemfile
CHANGED
@@ -1,23 +1,33 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
2
4
|
|
3
5
|
# Specify your gem's dependencies in config_module.gemspec
|
4
6
|
gemspec
|
5
7
|
|
6
|
-
if ENV[
|
8
|
+
if ENV["CI"] == "true"
|
7
9
|
group :test do
|
8
|
-
gem
|
9
|
-
gem
|
10
|
+
gem "simplecov"
|
11
|
+
gem "codeclimate-test-reporter", "~> 1.0.0"
|
10
12
|
end
|
11
13
|
else
|
12
14
|
group :development do
|
13
|
-
gem
|
15
|
+
gem "travis"
|
16
|
+
|
17
|
+
if RUBY_VERSION.to_f < 2.2
|
18
|
+
byebug_version = "~> 9.0.6"
|
19
|
+
elsif RUBY_VERSION.to_f < 2.3
|
20
|
+
byebug_version = "~> 10.0.2"
|
21
|
+
elsif RUBY_VERSION.to_f < 2.4
|
22
|
+
byebug_version = "< 12"
|
23
|
+
end
|
24
|
+
gem "byebug", byebug_version
|
14
25
|
|
15
|
-
gem
|
16
|
-
gem
|
17
|
-
gem
|
18
|
-
gem
|
19
|
-
gem
|
20
|
-
gem
|
21
|
-
gem 'pry-stack_explorer'
|
26
|
+
gem "pry"
|
27
|
+
gem "pry-doc"
|
28
|
+
gem "pry-theme"
|
29
|
+
gem "pry-rescue"
|
30
|
+
gem "pry-byebug"
|
31
|
+
gem "pry-coolline"
|
22
32
|
end
|
23
33
|
end
|
data/README.markdown
CHANGED
@@ -8,9 +8,9 @@ Reference documentation for the [Latest Released](http://rubydoc.info/gems/confi
|
|
8
8
|
[![Gem Version](https://img.shields.io/gem/v/config_module.svg)](https://rubygems.org/gems/config_module)
|
9
9
|
[![Gem Downloads](https://img.shields.io/gem/dt/config_module.svg?maxAge=2592000)](https://rubygems.org/gems/config_module)
|
10
10
|
[![Build Status](https://travis-ci.org/acook/config_module.svg?branch=master)](https://travis-ci.org/acook/config_module)
|
11
|
+
[![CircleCI](https://circleci.com/gh/acook/config_module.svg?style=svg)](https://circleci.com/gh/acook/config_module)
|
11
12
|
[![Code Climate](https://codeclimate.com/github/acook/config_module/badges/gpa.svg)](https://codeclimate.com/github/acook/config_module)
|
12
13
|
[![Test Coverage](https://codeclimate.com/github/acook/config_module/badges/coverage.svg)](https://codeclimate.com/github/acook/config_module/coverage)
|
13
|
-
[![Dependency Status](https://gemnasium.com/badges/github.com/acook/config_module.svg)](https://gemnasium.com/github.com/acook/config_module)
|
14
14
|
|
15
15
|
Installation
|
16
16
|
------------
|
data/Rakefile
CHANGED
data/config_module.gemspec
CHANGED
@@ -1,22 +1,24 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
5
|
+
require "config_module/version"
|
5
6
|
|
6
7
|
Gem::Specification.new do |gem|
|
7
|
-
gem.name
|
8
|
-
gem.version
|
9
|
-
gem.authors
|
10
|
-
gem.email
|
11
|
-
gem.description
|
12
|
-
|
13
|
-
gem.
|
14
|
-
gem.
|
8
|
+
gem.name = "config_module"
|
9
|
+
gem.version = ConfigModule::VERSION
|
10
|
+
gem.authors = ["Anthony M. Cook"]
|
11
|
+
gem.email = ["github@anthonymcook.com"]
|
12
|
+
gem.description =
|
13
|
+
"Wrap a configuration file in a module for easy use throughout your application. Inspired by Rails."
|
14
|
+
gem.summary = "Load important configuration files into their own modules!"
|
15
|
+
gem.homepage = "http://github.com/acook/config_module"
|
16
|
+
gem.licenses = %w[MIT LGPL-3.0]
|
15
17
|
|
16
|
-
gem.files
|
17
|
-
gem.executables
|
18
|
-
gem.test_files
|
19
|
-
gem.require_paths = [
|
18
|
+
gem.files = `git ls-files`.split($/)
|
19
|
+
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
20
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
21
|
+
gem.require_paths = ["lib"]
|
20
22
|
|
21
|
-
gem.add_development_dependency
|
23
|
+
gem.add_development_dependency "uspec", "~> 0.1.0"
|
22
24
|
end
|
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ConfigModule
|
2
4
|
class ConfigHelper
|
3
|
-
|
4
|
-
attr_accessor :config_file
|
5
|
+
attr_reader :raw_config
|
6
|
+
attr_accessor :config_file
|
7
|
+
attr_writer :namespaces
|
5
8
|
|
6
9
|
def config
|
7
10
|
@config ||= ConfigOption.wrap load_config
|
@@ -10,7 +13,7 @@ module ConfigModule
|
|
10
13
|
def method_missing_handler name, source, *args, &block
|
11
14
|
ConfigOption.wrap config.send(name, *args, &block)
|
12
15
|
rescue NoMethodError => error
|
13
|
-
if error.name == name
|
16
|
+
if error.name == name
|
14
17
|
raise(
|
15
18
|
ConfigOption::NotFoundError.new(name, self, error),
|
16
19
|
error.message, source
|
@@ -20,7 +23,11 @@ module ConfigModule
|
|
20
23
|
end
|
21
24
|
end
|
22
25
|
|
23
|
-
def
|
26
|
+
def respond_to_missing_handler name, include_all
|
27
|
+
config.send(:respond_to_missing?, name, include_all)
|
28
|
+
end
|
29
|
+
|
30
|
+
def field_lookup_handler name, _source, *_args, &_block
|
24
31
|
config[name]
|
25
32
|
end
|
26
33
|
|
@@ -31,7 +38,7 @@ module ConfigModule
|
|
31
38
|
end
|
32
39
|
|
33
40
|
def load_namespaces_from tree
|
34
|
-
namespaces.inject(ConfigOption.wrap
|
41
|
+
namespaces.inject(ConfigOption.wrap(tree)) do |subtree, ns|
|
35
42
|
if ConfigOption === subtree && ns.respond_to?(:to_sym) && subtree.has_key?(ns)
|
36
43
|
ConfigOption.wrap subtree[ns]
|
37
44
|
else
|
@@ -41,7 +48,7 @@ module ConfigModule
|
|
41
48
|
)
|
42
49
|
end
|
43
50
|
end
|
44
|
-
rescue TypeError
|
51
|
+
rescue TypeError
|
45
52
|
raise(
|
46
53
|
InvalidNamespaceError.new(namespaces.first, self, caller),
|
47
54
|
"Namespace must be a string or symbol, instead it was: #{namespaces.first.class}", caller(6)
|
@@ -49,7 +56,7 @@ module ConfigModule
|
|
49
56
|
end
|
50
57
|
|
51
58
|
def namespaces
|
52
|
-
@namespaces ||=
|
59
|
+
@namespaces ||= []
|
53
60
|
end
|
54
61
|
end
|
55
62
|
end
|
@@ -1,32 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ConfigModule
|
2
4
|
class ConfigOption < OpenStruct
|
3
5
|
include Enumerable
|
4
6
|
|
5
7
|
def self.wrap data
|
6
|
-
if data.is_a? Hash
|
7
|
-
|
8
|
+
if data.is_a? Hash
|
9
|
+
new data
|
8
10
|
else
|
9
11
|
data
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
13
|
-
def
|
14
|
-
return to_enum
|
15
|
-
@table.each_pair{|
|
15
|
+
def each_pair
|
16
|
+
return to_enum(__method__) { @table.size } unless block_given?
|
17
|
+
@table.each_pair { |pair| yield pair }
|
18
|
+
self
|
19
|
+
end
|
20
|
+
alias each each_pair
|
21
|
+
|
22
|
+
def each_key
|
23
|
+
return to_enum(__method__) { @table.size } unless block_given?
|
24
|
+
@table.each_key { |key| yield key }
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def each_value
|
29
|
+
return to_enum(__method__) { @table.size } unless block_given?
|
30
|
+
@table.each_value { |value| yield value }
|
31
|
+
self
|
16
32
|
end
|
17
33
|
|
18
|
-
|
19
|
-
|
34
|
+
unless public_instance_method :[]
|
35
|
+
def [] name
|
36
|
+
@table[name.to_sym]
|
37
|
+
end
|
20
38
|
end
|
21
39
|
|
22
40
|
def has_key? key
|
23
41
|
@table.has_key? key.to_sym
|
24
42
|
end
|
43
|
+
alias key? has_key?
|
25
44
|
|
26
45
|
def method_missing name, *args, &block
|
27
46
|
result = super
|
28
47
|
|
29
|
-
if result || @table.has_key?(name)
|
48
|
+
if result || @table.has_key?(name)
|
30
49
|
self.class.wrap result
|
31
50
|
else
|
32
51
|
raise(
|
@@ -34,7 +53,6 @@ module ConfigModule
|
|
34
53
|
"Key not found: #{name}", caller(3)
|
35
54
|
)
|
36
55
|
end
|
37
|
-
|
38
56
|
rescue NoMethodError => error
|
39
57
|
raise(
|
40
58
|
ConfigOption::NotFoundError.new(name, self, error),
|
@@ -42,13 +60,35 @@ module ConfigModule
|
|
42
60
|
)
|
43
61
|
end
|
44
62
|
|
45
|
-
def
|
46
|
-
name
|
47
|
-
|
48
|
-
|
49
|
-
|
63
|
+
def respond_to_missing? name, include_all
|
64
|
+
@table.has_key?(name) || super
|
65
|
+
end
|
66
|
+
private :respond_to_missing?
|
67
|
+
|
68
|
+
if private_instance_methods.include? :new_ostruct_member!
|
69
|
+
# :reek:TooManyStatements { max_statements: 10 }
|
70
|
+
def new_ostruct_member! name
|
71
|
+
name = name.to_sym
|
72
|
+
unless singleton_class.method_defined? name
|
73
|
+
define_singleton_method(name) { self.class.wrap @table[name] }
|
74
|
+
define_singleton_method("#{name}=") { |val| modifiable[name] = val }
|
75
|
+
end
|
76
|
+
name
|
77
|
+
end
|
78
|
+
private :new_ostruct_member!
|
79
|
+
alias new_ostruct_member new_ostruct_member! # :nodoc:
|
80
|
+
protected :new_ostruct_member
|
81
|
+
elsif instance_methods.include? :new_ostruct_member
|
82
|
+
# :reek:TooManyStatements { max_statements: 10 }
|
83
|
+
def new_ostruct_member name
|
84
|
+
name = name.to_sym
|
85
|
+
unless respond_to? name
|
86
|
+
define_singleton_method(name) { self.class.wrap @table[name] }
|
87
|
+
define_singleton_method("#{name}=") { |val| modifiable[name] = val }
|
88
|
+
end
|
89
|
+
name
|
50
90
|
end
|
51
|
-
|
91
|
+
protected :new_ostruct_member
|
52
92
|
end
|
53
93
|
|
54
94
|
class NotFoundError < ::ConfigModule::ConfigError
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ConfigModule
|
2
4
|
class ConfigError < NoMethodError
|
3
5
|
def initialize name, object, details = nil
|
4
6
|
@name, @object, @details = name, object, details
|
5
7
|
@custom_message = "invalid #{identifier} `#{name}' for #{object_info}"
|
6
8
|
end
|
7
|
-
|
9
|
+
attr_reader :name, :object, :details
|
8
10
|
|
9
11
|
def custom_message
|
10
12
|
@custom_message + "\n#{super_message}"
|
@@ -14,7 +16,7 @@ module ConfigModule
|
|
14
16
|
alias_method :message, :custom_message
|
15
17
|
|
16
18
|
def object_info
|
17
|
-
if object.is_a?(Class)
|
19
|
+
if object.is_a?(Class)
|
18
20
|
object.name
|
19
21
|
else
|
20
22
|
"instance of `#{object.class} < #{object.class.superclass}'"
|
data/lib/config_module.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
|
2
|
-
require 'yaml'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
require_relative
|
3
|
+
require "ostruct"
|
4
|
+
require "yaml"
|
5
|
+
|
6
|
+
require_relative "config_module/version"
|
7
|
+
require_relative "config_module/exceptions"
|
8
|
+
require_relative "config_module/config_option"
|
9
|
+
require_relative "config_module/config_helper"
|
8
10
|
|
9
11
|
module ConfigModule
|
10
12
|
def [] key, *args
|
@@ -35,7 +37,13 @@ private
|
|
35
37
|
@__config_module_helper ||= ConfigHelper.new
|
36
38
|
end
|
37
39
|
|
40
|
+
# rubocop:disable Style/MethodMissing
|
38
41
|
def method_missing name, *args, &block
|
39
|
-
__config_module_helper.method_missing_handler name, caller(1), *args
|
42
|
+
__config_module_helper.method_missing_handler name, caller(1), *args, &block
|
43
|
+
end
|
44
|
+
# rubocop:enable Style/MethodMissing
|
45
|
+
|
46
|
+
def respond_to_missing? name, include_all
|
47
|
+
__config_module_helper.respond_to_missing_handler(name, include_all) || super
|
40
48
|
end
|
41
49
|
end
|
data/uspec/config_helper_spec.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "spec_helper"
|
2
4
|
|
3
5
|
helper = ConfigModule::ConfigHelper.new
|
4
|
-
helper.config_file =
|
6
|
+
helper.config_file = "./config/example.yml"
|
5
7
|
|
6
|
-
spec
|
8
|
+
spec "method_missing_handler traces back to the caller" do
|
7
9
|
begin
|
8
10
|
helper.method_missing_handler :nonexistant, caller(1)
|
9
11
|
rescue NoMethodError => error
|
10
|
-
error.backtrace.to_s.include?
|
12
|
+
error.backtrace.to_s.include?("spec/config_helper_spec.rb:8:in") || error.backtrace
|
11
13
|
end
|
12
14
|
end
|
data/uspec/config_module_spec.rb
CHANGED
@@ -1,56 +1,78 @@
|
|
1
|
-
|
2
|
-
require_relative 'example_config'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
5
|
-
|
3
|
+
require_relative "spec_helper"
|
4
|
+
require_relative "example_config"
|
5
|
+
|
6
|
+
spec "modules extended with ConfigModule will load configurations" do
|
7
|
+
ExampleConfig.foo == "bar"
|
6
8
|
end
|
7
9
|
|
8
|
-
spec
|
10
|
+
spec "modules extended with ConfigModule have 'namespace' methods" do
|
9
11
|
ExampleConfig.methods.include? :namespace
|
10
12
|
end
|
11
13
|
|
12
|
-
spec
|
14
|
+
spec "config modules have [] methods" do
|
13
15
|
ExampleConfig.respond_to? :[]
|
14
16
|
end
|
15
17
|
|
16
|
-
spec
|
17
|
-
ExampleConfig[:foo] ==
|
18
|
+
spec "config modules return correct data using []" do
|
19
|
+
ExampleConfig[:foo] == "bar"
|
18
20
|
end
|
19
21
|
|
20
|
-
spec
|
21
|
-
ExampleConfig[:nonexistant]
|
22
|
+
spec "when using [], return nil for nonexistant keys" do
|
23
|
+
ExampleConfig[:nonexistant].nil?
|
22
24
|
end
|
23
25
|
|
24
|
-
spec
|
26
|
+
spec "nested hash values are properly wrapped" do
|
25
27
|
ExampleConfig.dictionary.class == ConfigModule::ConfigOption
|
26
28
|
end
|
27
29
|
|
28
|
-
spec
|
29
|
-
ExampleConfig.dictionary.
|
30
|
+
spec "nested hash values stay wrapped on subsequent calls" do
|
31
|
+
ExampleConfig.dictionary.class == ConfigModule::ConfigOption &&
|
32
|
+
ExampleConfig.dictionary.class == ConfigModule::ConfigOption
|
33
|
+
end
|
34
|
+
|
35
|
+
spec "subkeys are accessible with methods" do
|
36
|
+
ExampleConfig.dictionary.configuration == "An arrangement of elements in a particular form, figure, or combination."
|
37
|
+
end
|
38
|
+
|
39
|
+
spec "subkeys are accessible with methods on subsequent calls" do
|
40
|
+
ExampleConfig.dictionary.configuration
|
41
|
+
ExampleConfig.dictionary.configuration == "An arrangement of elements in a particular form, figure, or combination."
|
30
42
|
end
|
31
43
|
|
32
|
-
spec
|
33
|
-
text =
|
44
|
+
spec "subkeys work with .each" do
|
45
|
+
text = []
|
34
46
|
ExampleConfig.dictionary.each do |entry|
|
35
47
|
text << entry.to_s
|
36
48
|
end
|
37
|
-
text == "[:configuration, \"An arrangement of elements in a particular form, figure, or combination.\"]"
|
49
|
+
text.join == "[:configuration, \"An arrangement of elements in a particular form, figure, or combination.\"]"
|
50
|
+
end
|
51
|
+
|
52
|
+
spec "respond_to? works for top-level methods" do
|
53
|
+
ExampleConfig.respond_to?(:dictionary) &&
|
54
|
+
!ExampleConfig.respond_to?(:nonexistant)
|
55
|
+
end
|
56
|
+
|
57
|
+
spec "respond_to? works for subkey methods" do
|
58
|
+
ExampleConfig.dictionary.respond_to?(:configuration) &&
|
59
|
+
!ExampleConfig.dictionary.respond_to?(:nonexistant)
|
38
60
|
end
|
39
61
|
|
40
62
|
module FalseNil
|
41
63
|
extend ConfigModule
|
42
|
-
config_file
|
64
|
+
config_file "./config/false_nil.yml"
|
43
65
|
end
|
44
66
|
|
45
|
-
spec
|
67
|
+
spec "false values are returned" do
|
46
68
|
FalseNil.f == false
|
47
69
|
end
|
48
70
|
|
49
|
-
spec
|
50
|
-
FalseNil.n
|
71
|
+
spec "nil values are preserved" do
|
72
|
+
FalseNil.n.nil?
|
51
73
|
end
|
52
74
|
|
53
|
-
spec
|
75
|
+
spec "missing keys raise exception when called as methods" do
|
54
76
|
begin
|
55
77
|
FalseNil.nonexistant
|
56
78
|
rescue ConfigModule::ConfigOption::NotFoundError
|
@@ -60,24 +82,24 @@ end
|
|
60
82
|
|
61
83
|
module MultipleExample
|
62
84
|
extend ConfigModule
|
63
|
-
config_file
|
85
|
+
config_file "./config/example.yml"
|
64
86
|
namespace :production, :dictionary
|
65
87
|
end
|
66
88
|
|
67
|
-
spec
|
89
|
+
spec "multiple namespaces can be set" do
|
68
90
|
MultipleExample.configuration == ExampleConfig.dictionary.configuration
|
69
91
|
end
|
70
92
|
|
71
93
|
module InvalidNamespaceExample
|
72
94
|
extend ConfigModule
|
73
|
-
config_file
|
95
|
+
config_file "./config/example.yml"
|
74
96
|
namespace :jimmy, :pop, :ali
|
75
97
|
end
|
76
98
|
|
77
|
-
spec
|
99
|
+
spec "incorrect namespaces raise informative errors" do
|
78
100
|
begin
|
79
101
|
InvalidNamespaceExample.whatever
|
80
|
-
rescue
|
81
|
-
|
102
|
+
rescue ConfigModule::InvalidNamespaceError
|
103
|
+
true
|
82
104
|
end
|
83
105
|
end
|
data/uspec/config_option_spec.rb
CHANGED
@@ -1,40 +1,98 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative "spec_helper"
|
4
|
+
|
5
|
+
hash = { a: { b: 5 } }
|
4
6
|
opt = ConfigModule::ConfigOption.new hash
|
5
7
|
|
6
|
-
spec
|
8
|
+
spec "includes Enumerable (deprecated)" do
|
9
|
+
ConfigModule::ConfigOption.include?(Enumerable)
|
10
|
+
end
|
11
|
+
|
12
|
+
spec "responds to #[]" do
|
7
13
|
opt.respond_to? :[]
|
8
14
|
end
|
9
15
|
|
10
|
-
spec
|
16
|
+
spec "#[] returns value associated with key" do
|
11
17
|
opt[:a] == hash[:a]
|
12
18
|
end
|
13
19
|
|
14
|
-
spec
|
15
|
-
|
20
|
+
spec "supports each" do
|
21
|
+
x = []
|
22
|
+
opt.each { |k, v| x << [k, v] } == opt && x == [[:a, { b: 5 }]]
|
23
|
+
end
|
24
|
+
|
25
|
+
spec "supports each_pair" do
|
26
|
+
x = []
|
27
|
+
opt.each_pair { |k, v| x << [k, v] } == opt && x == [[:a, { b: 5 }]]
|
28
|
+
end
|
29
|
+
|
30
|
+
spec "supports each_key" do
|
31
|
+
x = []
|
32
|
+
opt.each_key { |k| x << k } == opt && x == [:a]
|
33
|
+
end
|
34
|
+
|
35
|
+
spec "supports each_value" do
|
36
|
+
x = []
|
37
|
+
opt.each_value { |v| x << v } == opt && x == [{ b: 5 }]
|
38
|
+
end
|
39
|
+
|
40
|
+
spec "supports each as enumerator" do
|
41
|
+
opt.each.class == Enumerator && opt.each.to_a == [[:a, { b: 5 }]]
|
42
|
+
end
|
43
|
+
|
44
|
+
spec "supports each_pair as enumerator" do
|
45
|
+
opt.each_pair.class == Enumerator && opt.each_pair.to_a == [[:a, { b: 5 }]]
|
46
|
+
end
|
47
|
+
|
48
|
+
spec "supports each_key as enumerator" do
|
49
|
+
opt.each_key.class == Enumerator && opt.each_key.to_a == [:a]
|
50
|
+
end
|
51
|
+
|
52
|
+
spec "supports each_value as enumerator" do
|
53
|
+
opt.each_value.class == Enumerator && opt.each_value.to_a == [{ b: 5 }]
|
54
|
+
end
|
55
|
+
|
56
|
+
spec "can be frozen" do
|
57
|
+
frozen = opt.dup.freeze
|
58
|
+
frozen.frozen?
|
59
|
+
end
|
60
|
+
|
61
|
+
spec "when frozen, defines methods which return the right results" do
|
62
|
+
frozen = opt.dup.freeze
|
63
|
+
frozen.a.class == ConfigModule::ConfigOption
|
64
|
+
end
|
65
|
+
|
66
|
+
spec "when frozen, does not freeze nested options" do
|
67
|
+
frozen = opt.dup.freeze
|
68
|
+
!frozen.a.frozen?
|
69
|
+
end
|
70
|
+
|
71
|
+
spec "when frozen, nested options still work" do
|
72
|
+
frozen = opt.dup.freeze
|
73
|
+
frozen.a.b == 5
|
16
74
|
end
|
17
75
|
|
18
|
-
spec
|
76
|
+
spec "identifies the presence of keys" do
|
19
77
|
opt.has_key? :a
|
20
78
|
end
|
21
79
|
|
22
|
-
spec
|
23
|
-
opt.has_key?
|
80
|
+
spec "identifies the presence of keys as strings" do
|
81
|
+
opt.has_key? "a"
|
24
82
|
end
|
25
83
|
|
26
|
-
spec
|
27
|
-
opt.has_key?(
|
84
|
+
spec "identifies the lack of keys" do
|
85
|
+
opt.has_key?("nonexistant") == false
|
28
86
|
end
|
29
87
|
|
30
|
-
spec
|
88
|
+
spec "identifies the presence of nested keys" do
|
31
89
|
opt.a.has_key? :b
|
32
90
|
end
|
33
91
|
|
34
|
-
spec
|
92
|
+
spec "to_ary" do
|
35
93
|
begin
|
36
94
|
opt.to_ary
|
37
|
-
rescue
|
38
|
-
|
95
|
+
rescue ConfigModule::ConfigOption::NotFoundError
|
96
|
+
true
|
39
97
|
end
|
40
98
|
end
|
data/uspec/example_config.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ExampleConfig
|
2
4
|
extend ConfigModule
|
3
5
|
|
4
|
-
config_file
|
6
|
+
config_file "./config/example.yml"
|
5
7
|
namespace Rails.env
|
6
8
|
|
7
|
-
|
9
|
+
module_function
|
8
10
|
|
9
11
|
def kanoodle
|
10
|
-
|
12
|
+
"ka" + config.noodle
|
11
13
|
end
|
12
14
|
end
|
data/uspec/exceptions_spec.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative "spec_helper"
|
4
|
+
|
5
|
+
spec "display appropriate error when the object is a class" do
|
4
6
|
error = ConfigModule::InvalidNamespaceError.new :foo, Array
|
5
|
-
error.message.include?
|
7
|
+
error.message.include?("Array") || error.message
|
6
8
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
-
|
2
|
-
require_relative 'example_config'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
3
|
+
require_relative "spec_helper"
|
4
|
+
require_relative "example_config"
|
5
|
+
|
6
|
+
spec "method missing must handle multiple arguments gracefully" do
|
5
7
|
begin
|
6
8
|
ExampleConfig.nonexistant :foo, :bar
|
7
9
|
rescue NoMethodError => error
|
data/uspec/namespace_spec.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "spec_helper"
|
2
4
|
|
3
5
|
def self.helper
|
4
|
-
|
5
|
-
else
|
6
|
+
@helper ||= begin
|
6
7
|
@helper = ConfigModule::ConfigHelper.new
|
7
|
-
@helper.config_file =
|
8
|
-
@helper.namespaces = [
|
8
|
+
@helper.config_file = "./config/example.yml"
|
9
|
+
@helper.namespaces = ["production"]
|
9
10
|
@helper.config
|
10
11
|
@helper
|
11
12
|
end
|
@@ -13,58 +14,55 @@ end
|
|
13
14
|
|
14
15
|
table = helper.load_config.instance_variable_get(:@table)
|
15
16
|
|
16
|
-
spec
|
17
|
+
spec "namespaces obtain subtrees of the full config" do
|
17
18
|
table.keys == [:foo, :noodle, :dictionary]
|
18
19
|
end
|
19
20
|
|
20
|
-
spec
|
21
|
-
symbolized_keys_from_full_config = helper.raw_config[
|
21
|
+
spec "specifying a namespace forces #config to return that subtree the first time its called" do
|
22
|
+
symbolized_keys_from_full_config = helper.raw_config["production"].keys.map(&:to_sym)
|
22
23
|
symbolized_keys_from_full_config == table.keys
|
23
24
|
end
|
24
25
|
|
25
|
-
spec
|
26
|
+
spec "nested namespaces are handled properly" do
|
26
27
|
helper = ConfigModule::ConfigHelper.new
|
27
|
-
helper.config_file =
|
28
|
-
helper.namespaces = [
|
29
|
-
helper.config.has_key?(
|
30
|
-
helper.config[:configuration] == helper.raw_config[
|
28
|
+
helper.config_file = "./config/example.yml"
|
29
|
+
helper.namespaces = %w[production dictionary]
|
30
|
+
helper.config.has_key?("configuration") &&
|
31
|
+
helper.config[:configuration] == helper.raw_config["production"]["dictionary"]["configuration"]
|
31
32
|
end
|
32
33
|
|
33
|
-
spec
|
34
|
+
spec "misconfigured namespaces provide useful errors" do
|
34
35
|
helper = ConfigModule::ConfigHelper.new
|
35
|
-
helper.config_file =
|
36
|
-
helper.namespaces = [
|
36
|
+
helper.config_file = "./config/example.yml"
|
37
|
+
helper.namespaces = ["nonexistant"]
|
37
38
|
|
38
39
|
begin
|
39
40
|
helper.config
|
40
41
|
rescue ConfigModule::InvalidNamespaceError => error
|
41
|
-
error.
|
42
|
-
error.message.include?('nonexistant') || error.message
|
42
|
+
error.message.include?("nonexistant") || error.message
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
spec
|
46
|
+
spec "out of bounds namespaces are checked properly" do
|
47
47
|
helper = ConfigModule::ConfigHelper.new
|
48
|
-
helper.config_file =
|
49
|
-
helper.namespaces = [
|
48
|
+
helper.config_file = "./config/example.yml"
|
49
|
+
helper.namespaces = %w[production foo bar]
|
50
50
|
|
51
51
|
begin
|
52
52
|
helper.config
|
53
53
|
rescue ConfigModule::InvalidNamespaceError => error
|
54
|
-
error.
|
55
|
-
error.message.include?('bar') || error.message
|
54
|
+
error.message.include?("bar") || error.message
|
56
55
|
end
|
57
56
|
end
|
58
57
|
|
59
|
-
spec
|
58
|
+
spec "invalid namespaces which are ruby objects display properly" do
|
60
59
|
helper = ConfigModule::ConfigHelper.new
|
61
|
-
helper.config_file =
|
62
|
-
helper.namespaces = [Array,Hash]
|
60
|
+
helper.config_file = "./config/example.yml"
|
61
|
+
helper.namespaces = [Array, Hash]
|
63
62
|
|
64
63
|
begin
|
65
64
|
helper.config
|
66
65
|
rescue ConfigModule::InvalidNamespaceError => error
|
67
|
-
error.
|
68
|
-
error.message.include?('Array') || error.message
|
66
|
+
error.message.include?("Array") || error.message
|
69
67
|
end
|
70
68
|
end
|
data/uspec/spec_helper.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "uspec"
|
3
5
|
Bundler.require :default, :test
|
4
6
|
|
5
|
-
if ENV[
|
6
|
-
require
|
7
|
+
if ENV["CI"] == "true"
|
8
|
+
require "simplecov"
|
7
9
|
SimpleCov.start
|
8
10
|
end
|
9
11
|
|
10
12
|
Dir.chdir File.dirname(__FILE__)
|
11
13
|
|
12
|
-
require_relative
|
14
|
+
require_relative "../lib/config_module"
|
13
15
|
|
14
16
|
extend Uspec
|
15
17
|
|
16
|
-
module Rails; def self.env;
|
18
|
+
module Rails; def self.env; "production"; end; end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: config_module
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anthony M. Cook
|
@@ -14,16 +14,16 @@ dependencies:
|
|
14
14
|
name: uspec
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.1.0
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 0.1.0
|
27
27
|
description: Wrap a configuration file in a module for easy use throughout your application.
|
28
28
|
Inspired by Rails.
|
29
29
|
email:
|
@@ -32,8 +32,11 @@ executables: []
|
|
32
32
|
extensions: []
|
33
33
|
extra_rdoc_files: []
|
34
34
|
files:
|
35
|
+
- ".circleci/config.yml"
|
35
36
|
- ".codeclimate.yml"
|
36
37
|
- ".gitignore"
|
38
|
+
- ".gitlab-ci.yml"
|
39
|
+
- ".rubocop.yml"
|
37
40
|
- ".ruby-gemset"
|
38
41
|
- ".ruby-version"
|
39
42
|
- ".travis.yml"
|
@@ -59,7 +62,7 @@ files:
|
|
59
62
|
homepage: http://github.com/acook/config_module
|
60
63
|
licenses:
|
61
64
|
- MIT
|
62
|
-
- LGPL-3
|
65
|
+
- LGPL-3.0
|
63
66
|
metadata: {}
|
64
67
|
post_install_message:
|
65
68
|
rdoc_options: []
|