active_setting 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.hound.yml +2 -0
- data/.rspec +3 -0
- data/.rubocop.yml +11 -0
- data/.ruby-style.yml +233 -0
- data/.ruby-version +1 -0
- data/.travis.yml +11 -0
- data/Gemfile +2 -0
- data/README.md +25 -0
- data/Rakefile +12 -0
- data/active_setting.gemspec +30 -0
- data/lib/active_setting.rb +4 -0
- data/lib/active_setting/loader.rb +84 -0
- data/lib/active_setting/setting.rb +128 -0
- data/lib/active_setting/version.rb +3 -0
- data/spec/loader_spec.rb +73 -0
- data/spec/setting_spec.rb +80 -0
- data/spec/settings.yml +16 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/support/coverage_loader.rb +26 -0
- metadata +180 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6d905b6225a4c743215e6f56aee659741c83b4c7
|
4
|
+
data.tar.gz: 6956767bbc1c17ad2a3584fa8ea1790de01467f2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3e098853466eceae1c2314305c732de831e83fe1f3eec075b6cb8fc86c6503833c98bd7e424edb9fe6faa4b74d872055026d7d307fabadc4521551d7cd1b79bf
|
7
|
+
data.tar.gz: 9cff93d5a668cae4d80f6107c38db9d69be6612411f54824b420512a524acc02028fb4635ead2c1b68f341c4fc79e8933d91cd4861ff8b3a520adc938d8ff615
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Gemfile.lock
|
2
|
+
|
3
|
+
# tests
|
4
|
+
coverage
|
5
|
+
|
6
|
+
# Bundler related
|
7
|
+
/vendor/bundle
|
8
|
+
/vendor/ruby
|
9
|
+
/bundle
|
10
|
+
/.bundle
|
11
|
+
|
12
|
+
# other
|
13
|
+
/.redcar
|
14
|
+
/nbproject
|
15
|
+
/.project
|
16
|
+
/.idea
|
17
|
+
/.eclipse
|
18
|
+
*.sublime-project
|
19
|
+
*.sublime-workspace
|
20
|
+
|
21
|
+
# Mac specific directory information
|
22
|
+
*.DS_Store
|
data/.hound.yml
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.ruby-style.yml
ADDED
@@ -0,0 +1,233 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- "vendor/**/*"
|
4
|
+
- "db/schema.rb"
|
5
|
+
UseCache: false
|
6
|
+
Style/CollectionMethods:
|
7
|
+
Description: Preferred collection methods.
|
8
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#map-find-select-reduce-size
|
9
|
+
Enabled: true
|
10
|
+
PreferredMethods:
|
11
|
+
collect: map
|
12
|
+
collect!: map!
|
13
|
+
find: detect
|
14
|
+
find_all: select
|
15
|
+
reduce: inject
|
16
|
+
Style/DotPosition:
|
17
|
+
Description: Checks the position of the dot in multi-line method calls.
|
18
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains
|
19
|
+
Enabled: true
|
20
|
+
EnforcedStyle: trailing
|
21
|
+
SupportedStyles:
|
22
|
+
- leading
|
23
|
+
- trailing
|
24
|
+
Style/FileName:
|
25
|
+
Description: Use snake_case for source file names.
|
26
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-files
|
27
|
+
Enabled: false
|
28
|
+
Exclude: []
|
29
|
+
Style/GuardClause:
|
30
|
+
Description: Check for conditionals that can be replaced with guard clauses
|
31
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals
|
32
|
+
Enabled: false
|
33
|
+
MinBodyLength: 1
|
34
|
+
Style/IfUnlessModifier:
|
35
|
+
Description: Favor modifier if/unless usage when you have a single-line body.
|
36
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier
|
37
|
+
Enabled: false
|
38
|
+
MaxLineLength: 100
|
39
|
+
Style/OptionHash:
|
40
|
+
Description: Don't use option hashes when you can use keyword arguments.
|
41
|
+
Enabled: false
|
42
|
+
Style/PercentLiteralDelimiters:
|
43
|
+
Description: Use `%`-literal delimiters consistently
|
44
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-literal-braces
|
45
|
+
Enabled: false
|
46
|
+
PreferredDelimiters:
|
47
|
+
"%": "()"
|
48
|
+
"%i": "()"
|
49
|
+
"%q": "()"
|
50
|
+
"%Q": "()"
|
51
|
+
"%r": "{}"
|
52
|
+
"%s": "()"
|
53
|
+
"%w": "()"
|
54
|
+
"%W": "()"
|
55
|
+
"%x": "()"
|
56
|
+
Style/PredicateName:
|
57
|
+
Description: Check the names of predicate methods.
|
58
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark
|
59
|
+
Enabled: true
|
60
|
+
NamePrefix:
|
61
|
+
- is_
|
62
|
+
- has_
|
63
|
+
- have_
|
64
|
+
NamePrefixBlacklist:
|
65
|
+
- is_
|
66
|
+
Exclude:
|
67
|
+
- spec/**/*
|
68
|
+
Style/RaiseArgs:
|
69
|
+
Description: Checks the arguments passed to raise/fail.
|
70
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#exception-class-messages
|
71
|
+
Enabled: false
|
72
|
+
EnforcedStyle: exploded
|
73
|
+
SupportedStyles:
|
74
|
+
- compact
|
75
|
+
- exploded
|
76
|
+
Style/SignalException:
|
77
|
+
Description: Checks for proper usage of fail and raise.
|
78
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#fail-method
|
79
|
+
Enabled: false
|
80
|
+
EnforcedStyle: semantic
|
81
|
+
SupportedStyles:
|
82
|
+
- only_raise
|
83
|
+
- only_fail
|
84
|
+
- semantic
|
85
|
+
Style/SingleLineBlockParams:
|
86
|
+
Description: Enforces the names of some block params.
|
87
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#reduce-blocks
|
88
|
+
Enabled: false
|
89
|
+
Methods:
|
90
|
+
- reduce:
|
91
|
+
- a
|
92
|
+
- e
|
93
|
+
- inject:
|
94
|
+
- a
|
95
|
+
- e
|
96
|
+
Style/SingleLineMethods:
|
97
|
+
Description: Avoid single-line methods.
|
98
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-single-line-methods
|
99
|
+
Enabled: false
|
100
|
+
AllowIfMethodIsEmpty: true
|
101
|
+
Style/StringLiterals:
|
102
|
+
Description: Checks if uses of quotes match the configured preference.
|
103
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-string-literals
|
104
|
+
Enabled: true
|
105
|
+
EnforcedStyle: single_quotes
|
106
|
+
SupportedStyles:
|
107
|
+
- single_quotes
|
108
|
+
- double_quotes
|
109
|
+
Style/StringLiteralsInInterpolation:
|
110
|
+
Description: Checks if uses of quotes inside expressions in interpolated strings
|
111
|
+
match the configured preference.
|
112
|
+
Enabled: true
|
113
|
+
EnforcedStyle: single_quotes
|
114
|
+
SupportedStyles:
|
115
|
+
- single_quotes
|
116
|
+
- double_quotes
|
117
|
+
Style/TrailingComma:
|
118
|
+
Description: Checks for trailing comma in parameter lists and literals.
|
119
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas
|
120
|
+
Enabled: false
|
121
|
+
EnforcedStyleForMultiline: no_comma
|
122
|
+
SupportedStyles:
|
123
|
+
- comma
|
124
|
+
- no_comma
|
125
|
+
Metrics/AbcSize:
|
126
|
+
Description: A calculated magnitude based on number of assignments, branches, and
|
127
|
+
conditions.
|
128
|
+
Enabled: false
|
129
|
+
Max: 15
|
130
|
+
Metrics/ClassLength:
|
131
|
+
Description: Avoid classes longer than 100 lines of code.
|
132
|
+
Enabled: false
|
133
|
+
CountComments: false
|
134
|
+
Max: 100
|
135
|
+
Metrics/ModuleLength:
|
136
|
+
CountComments: false
|
137
|
+
Max: 100
|
138
|
+
Description: Avoid modules longer than 100 lines of code.
|
139
|
+
Enabled: false
|
140
|
+
Metrics/CyclomaticComplexity:
|
141
|
+
Description: A complexity metric that is strongly correlated to the number of test
|
142
|
+
cases needed to validate a method.
|
143
|
+
Enabled: false
|
144
|
+
Max: 6
|
145
|
+
Metrics/MethodLength:
|
146
|
+
Description: Avoid methods longer than 10 lines of code.
|
147
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#short-methods
|
148
|
+
Enabled: false
|
149
|
+
CountComments: false
|
150
|
+
Max: 10
|
151
|
+
Metrics/ParameterLists:
|
152
|
+
Description: Avoid parameter lists longer than three or four parameters.
|
153
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#too-many-params
|
154
|
+
Enabled: false
|
155
|
+
Max: 5
|
156
|
+
CountKeywordArgs: true
|
157
|
+
Metrics/PerceivedComplexity:
|
158
|
+
Description: A complexity metric geared towards measuring complexity for a human
|
159
|
+
reader.
|
160
|
+
Enabled: false
|
161
|
+
Max: 7
|
162
|
+
Lint/AssignmentInCondition:
|
163
|
+
Description: Don't use assignment in conditions.
|
164
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition
|
165
|
+
Enabled: false
|
166
|
+
AllowSafeAssignment: true
|
167
|
+
Style/InlineComment:
|
168
|
+
Description: Avoid inline comments.
|
169
|
+
Enabled: false
|
170
|
+
Style/AccessorMethodName:
|
171
|
+
Description: Check the naming of accessor methods for get_/set_.
|
172
|
+
Enabled: false
|
173
|
+
Style/Alias:
|
174
|
+
Description: Use alias_method instead of alias.
|
175
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#alias-method
|
176
|
+
Enabled: false
|
177
|
+
Style/Documentation:
|
178
|
+
Description: Document classes and non-namespace modules.
|
179
|
+
Enabled: false
|
180
|
+
Style/DoubleNegation:
|
181
|
+
Description: Checks for uses of double negation (!!).
|
182
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-bang-bang
|
183
|
+
Enabled: false
|
184
|
+
Style/EachWithObject:
|
185
|
+
Description: Prefer `each_with_object` over `inject` or `reduce`.
|
186
|
+
Enabled: false
|
187
|
+
Style/EmptyLiteral:
|
188
|
+
Description: Prefer literals to Array.new/Hash.new/String.new.
|
189
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#literal-array-hash
|
190
|
+
Enabled: false
|
191
|
+
Style/ModuleFunction:
|
192
|
+
Description: Checks for usage of `extend self` in modules.
|
193
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#module-function
|
194
|
+
Enabled: false
|
195
|
+
Style/OneLineConditional:
|
196
|
+
Description: Favor the ternary operator(?:) over if/then/else/end constructs.
|
197
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#ternary-operator
|
198
|
+
Enabled: false
|
199
|
+
Style/PerlBackrefs:
|
200
|
+
Description: Avoid Perl-style regex back references.
|
201
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers
|
202
|
+
Enabled: false
|
203
|
+
Style/Send:
|
204
|
+
Description: Prefer `Object#__send__` or `Object#public_send` to `send`, as `send`
|
205
|
+
may overlap with existing methods.
|
206
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#prefer-public-send
|
207
|
+
Enabled: false
|
208
|
+
Style/SpecialGlobalVars:
|
209
|
+
Description: Avoid Perl-style global variables.
|
210
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms
|
211
|
+
Enabled: false
|
212
|
+
Style/VariableInterpolation:
|
213
|
+
Description: Don't interpolate global, instance and class variables directly in
|
214
|
+
strings.
|
215
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#curlies-interpolate
|
216
|
+
Enabled: false
|
217
|
+
Style/WhenThen:
|
218
|
+
Description: Use when x then ... for one-line cases.
|
219
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#one-line-cases
|
220
|
+
Enabled: false
|
221
|
+
Lint/EachWithObjectArgument:
|
222
|
+
Description: Check for immutable argument given to each_with_object.
|
223
|
+
Enabled: true
|
224
|
+
Lint/HandleExceptions:
|
225
|
+
Description: Don't suppress exception.
|
226
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions
|
227
|
+
Enabled: false
|
228
|
+
Lint/LiteralInCondition:
|
229
|
+
Description: Checks of literals used in conditions.
|
230
|
+
Enabled: false
|
231
|
+
Lint/LiteralInInterpolation:
|
232
|
+
Description: Checks for literals used in interpolation.
|
233
|
+
Enabled: false
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.3
|
data/.travis.yml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 2.3.0
|
4
|
+
script: bundle exec rake spec
|
5
|
+
notifications:
|
6
|
+
email:
|
7
|
+
- support@travellink.com.au
|
8
|
+
flowdock:
|
9
|
+
secure: me2eIi9fkTSgFFMffEr7uOIkrArm//5I00W8l/Raea30jI+BgTy/yC9gs8Bn/fyxQTjEWMkAQokSvFYia7TCyHuTd5ogz+rYzCUI5dxo9kw7Q+EzBNTGUBsVsL69sLHhVOkIt1IlOeiuwY3KeGn+vo5ICK9MNM1ggTIY1+NB+ic=
|
10
|
+
sudo: false
|
11
|
+
cache: bundler
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
Setting
|
2
|
+
=======
|
3
|
+
|
4
|
+
[](https://travis-ci.org/sealink/active_setting)
|
5
|
+
[](https://gemnasium.com/sealink/active_setting)
|
6
|
+
[](https://codeclimate.com/github/sealink/active_setting)
|
7
|
+
|
8
|
+
# DESCRIPTION
|
9
|
+
|
10
|
+
A library for managing settings with various values/defaults/etc.
|
11
|
+
|
12
|
+
# INSTALLATION
|
13
|
+
|
14
|
+
gem install setting
|
15
|
+
|
16
|
+
or add to your Gemfile:
|
17
|
+
gem 'setting'
|
18
|
+
|
19
|
+
# SYNOPSIS
|
20
|
+
|
21
|
+
require 'setting'
|
22
|
+
|
23
|
+
For examples on most usage see the tests in the spec directory.
|
24
|
+
As these contain many basic examples with expected output.
|
25
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
desc 'Default: run specs.'
|
4
|
+
task :default => :spec
|
5
|
+
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
|
8
|
+
desc "Run specs"
|
9
|
+
RSpec::Core::RakeTask.new do |t|
|
10
|
+
t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
|
11
|
+
# Put spec opts in a file named .rspec in root
|
12
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'active_setting/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'active_setting'
|
8
|
+
spec.version = ActiveSetting::VERSION
|
9
|
+
spec.authors = ["Michael Noack"]
|
10
|
+
spec.email = 'support@travellink.com.au'
|
11
|
+
spec.description = "See README for full details on how to install, use, etc."
|
12
|
+
spec.summary = "Store active_settings of various data types"
|
13
|
+
spec.homepage = 'http://github.com/sealink/active_setting'
|
14
|
+
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files`.split($/)
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency 'bundler'
|
23
|
+
spec.add_development_dependency 'rake'
|
24
|
+
spec.add_development_dependency 'rspec', '~> 3.4'
|
25
|
+
spec.add_development_dependency 'simplecov'
|
26
|
+
spec.add_development_dependency 'simplecov-rcov'
|
27
|
+
spec.add_development_dependency 'coveralls'
|
28
|
+
spec.add_development_dependency 'rubocop'
|
29
|
+
spec.add_development_dependency 'travis'
|
30
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module ActiveSetting
|
4
|
+
class Loader
|
5
|
+
class << self
|
6
|
+
def load_settings(filename = nil)
|
7
|
+
new(filename).load_settings
|
8
|
+
end
|
9
|
+
|
10
|
+
def build_hash(filename = nil)
|
11
|
+
new(filename).build_hash
|
12
|
+
end
|
13
|
+
|
14
|
+
def config_filename
|
15
|
+
@config_filename || 'settings.yml'
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_writer :config_filename
|
19
|
+
|
20
|
+
def external_settings
|
21
|
+
@external_settings ||= {}
|
22
|
+
end
|
23
|
+
|
24
|
+
def register_external_setting(name, attrs)
|
25
|
+
category ||= external_settings[attrs.fetch(:category, 'External')] ||= {}
|
26
|
+
category[name] = attrs.map.with_object({}) { |(k,v), hash| hash[k.to_s] = v }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(config_filename = nil)
|
31
|
+
@config_filename = config_filename
|
32
|
+
end
|
33
|
+
|
34
|
+
def config_filename
|
35
|
+
@config_filename || self.class.config_filename
|
36
|
+
end
|
37
|
+
|
38
|
+
def load_settings
|
39
|
+
settings_config.each do |category_name, settings|
|
40
|
+
settings.each do |setting_name, values|
|
41
|
+
attrs = values.merge(
|
42
|
+
data_type: values['type'],
|
43
|
+
category: category_name,
|
44
|
+
name: setting_name
|
45
|
+
)
|
46
|
+
Setting.register(setting_name.to_sym, attrs)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def build_hash
|
52
|
+
settings_config.map.with_object({}) do |(category_name, settings), hash|
|
53
|
+
settings.each do |setting_name, values|
|
54
|
+
attrs = values.merge(
|
55
|
+
data_type: values['type'],
|
56
|
+
category: category_name,
|
57
|
+
name: setting_name.to_sym
|
58
|
+
)
|
59
|
+
hash[setting_name.to_sym] = Setting.new(attrs)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def settings_config
|
67
|
+
@settings_config ||= settings_from_file.merge(external_settings)
|
68
|
+
end
|
69
|
+
|
70
|
+
def external_settings
|
71
|
+
self.class.external_settings
|
72
|
+
end
|
73
|
+
|
74
|
+
def settings_from_file
|
75
|
+
return @settings_from_file unless @settings_from_file.nil?
|
76
|
+
|
77
|
+
unless File.exist? config_filename
|
78
|
+
fail ArgumentError, "#{config_filename} is required for settings"
|
79
|
+
end
|
80
|
+
yaml = YAML.load(File.read(config_filename))
|
81
|
+
@settings_from_file = yaml.fetch('settings')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
3
|
+
module ActiveSetting
|
4
|
+
class Setting # < ActiveRecord::Base
|
5
|
+
attr_accessor :name, :description, :category, :raw_value, :default
|
6
|
+
attr_reader :data_type, :subtype, :options
|
7
|
+
|
8
|
+
def self.registered_settings
|
9
|
+
@registered_settings ||= {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(attr = {})
|
13
|
+
attr.each do |key, value|
|
14
|
+
setter = "#{key}="
|
15
|
+
send(setter, value) if respond_to?(setter)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.register(name, options)
|
20
|
+
new(options.merge(name: name)).register
|
21
|
+
end
|
22
|
+
|
23
|
+
def register
|
24
|
+
self.class.registered_settings[name.to_sym] = self
|
25
|
+
Setting.define_shortcut_method(self)
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.define_shortcut_method(setting)
|
30
|
+
class_eval <<-TEXT
|
31
|
+
def self.#{setting.name}
|
32
|
+
self.class.registered_settings[:#{setting.name}].value
|
33
|
+
end
|
34
|
+
def self.#{setting.name}=(value)
|
35
|
+
self.class.registered_settings[:#{setting.name}].raw_value = value
|
36
|
+
end
|
37
|
+
TEXT
|
38
|
+
end
|
39
|
+
|
40
|
+
def setting
|
41
|
+
self.class.registered_settings[@name.to_sym]
|
42
|
+
end
|
43
|
+
|
44
|
+
def data_type=(data_type)
|
45
|
+
@data_type = data_type.to_sym if data_type
|
46
|
+
end
|
47
|
+
|
48
|
+
def subtype=(subtype)
|
49
|
+
@subtype = subtype.to_sym if subtype
|
50
|
+
end
|
51
|
+
|
52
|
+
def options
|
53
|
+
@object_options ? calculate_object_options : @options
|
54
|
+
end
|
55
|
+
|
56
|
+
def options=(options)
|
57
|
+
@options = options.split(' ')
|
58
|
+
end
|
59
|
+
|
60
|
+
attr_writer :object_options
|
61
|
+
|
62
|
+
# <b>DEPRECATED:</b> Please use standard options instead.
|
63
|
+
def calculate_object_options
|
64
|
+
puts '[WARNING] ActiveSetting::Setting#object_options is deprecated'\
|
65
|
+
' as it poses a serious security risk and will be removed in future versions'
|
66
|
+
|
67
|
+
objects, key, value = @object_options.split(' ')
|
68
|
+
value = key if value.nil? || value == ''
|
69
|
+
# TODO: Remove this method, as it uses eval !!!
|
70
|
+
objects_from_collection(eval(objects), key, value)
|
71
|
+
end
|
72
|
+
|
73
|
+
def objects_from_collection(collection, key, value)
|
74
|
+
collection.map { |o| [o.send(key), o.send(value)] }
|
75
|
+
end
|
76
|
+
|
77
|
+
def raw_value=(new)
|
78
|
+
@value = nil
|
79
|
+
@raw_value = new
|
80
|
+
end
|
81
|
+
|
82
|
+
def value
|
83
|
+
v = raw_value || default
|
84
|
+
|
85
|
+
# TODO: WHY IS the first line here
|
86
|
+
return nil if v.nil?
|
87
|
+
|
88
|
+
@value ||= build_value(v)
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.convert_value(val, data_type)
|
92
|
+
case data_type
|
93
|
+
when :boolean then ![nil, false, 'false', 0, '0'].include?(val)
|
94
|
+
when :integer then val.to_i
|
95
|
+
when :string then val.to_s
|
96
|
+
when :symbol then val.to_sym
|
97
|
+
when :decimal then BigDecimal(val)
|
98
|
+
else val
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def build_value(v)
|
105
|
+
case data_type
|
106
|
+
when :hash
|
107
|
+
hash_value(v)
|
108
|
+
when :csv
|
109
|
+
csv_value(v)
|
110
|
+
else
|
111
|
+
Setting.convert_value(v, data_type)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def hash_value(v)
|
116
|
+
chunks = v.split(',')
|
117
|
+
chunks.map.with_object({}) do |val, h|
|
118
|
+
key, subval = val.split(':').map(&:strip)
|
119
|
+
h[key.to_sym] = subval
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def csv_value(v)
|
124
|
+
return v if v.empty? # e.g. default = []
|
125
|
+
v.split(',').map(&:strip).map { |e| Setting.convert_value(e, subtype) }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
data/spec/loader_spec.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveSetting::Loader do
|
4
|
+
let(:config_filename) { 'spec/settings.yml' }
|
5
|
+
|
6
|
+
it 'should parse a settings file to get settings' do
|
7
|
+
ActiveSetting::Loader.load_settings(config_filename)
|
8
|
+
settings = ActiveSetting::Setting.registered_settings
|
9
|
+
settings.keys.should include :maximum_percent
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when building a settings hash from the settings file' do
|
13
|
+
let(:hash) { ActiveSetting::Loader.build_hash(config_filename) }
|
14
|
+
let(:source) { YAML.load(File.read(config_filename))['settings'] }
|
15
|
+
|
16
|
+
context 'maximum percent setting' do
|
17
|
+
let(:setting) { hash[:maximum_percent] }
|
18
|
+
specify { expect(setting).to be_a ActiveSetting::Setting }
|
19
|
+
specify { expect(setting.name).to eq :maximum_percent }
|
20
|
+
specify { expect(setting.category).to eq 'general_category' }
|
21
|
+
specify { expect(setting.data_type).to eq :integer }
|
22
|
+
specify { expect(setting.default).to eq 50 }
|
23
|
+
specify { expect(setting.description).to eq 'The minimum percentage to pass' }
|
24
|
+
specify { expect(setting.options).to be_nil }
|
25
|
+
specify { expect(setting.value).to eq 50 }
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'difficulty setting' do
|
29
|
+
let(:setting) { hash[:difficulty] }
|
30
|
+
specify { expect(setting).to be_a ActiveSetting::Setting }
|
31
|
+
specify { expect(setting.name).to eq :difficulty }
|
32
|
+
specify { expect(setting.category).to eq 'general_category' }
|
33
|
+
specify { expect(setting.options).to eq %w(easy normal hard) }
|
34
|
+
specify { expect(setting.value).to be_nil }
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'product ids setting' do
|
38
|
+
let(:setting) { hash[:product_ids] }
|
39
|
+
specify { expect(setting).to be_a ActiveSetting::Setting }
|
40
|
+
specify { expect(setting.name).to eq :product_ids }
|
41
|
+
specify { expect(setting.category).to eq 'general_category' }
|
42
|
+
specify { expect(setting.data_type).to eq :csv }
|
43
|
+
specify { expect(setting.subtype).to eq :integer }
|
44
|
+
specify { expect(setting.value).to eq [1, 2, 3] }
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'testing setting' do
|
48
|
+
let(:setting) { hash[:testing] }
|
49
|
+
specify { expect(setting).to be_a ActiveSetting::Setting }
|
50
|
+
specify { expect(setting.name).to eq :testing }
|
51
|
+
specify { expect(setting.category).to eq 'general_category' }
|
52
|
+
specify { expect(setting.data_type).to eq :boolean }
|
53
|
+
specify { expect(setting.value).to eq true }
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when external settings are defined' do
|
57
|
+
before do
|
58
|
+
ActiveSetting::Loader.register_external_setting(
|
59
|
+
:externally_defined,
|
60
|
+
type: 'string',
|
61
|
+
default: 'external setting'
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
let(:setting) { hash[:externally_defined] }
|
66
|
+
specify { expect(setting).to be_a ActiveSetting::Setting }
|
67
|
+
specify { expect(setting.name).to eq :externally_defined }
|
68
|
+
specify { expect(setting.category).to eq 'External' }
|
69
|
+
specify { expect(setting.data_type).to eq :string }
|
70
|
+
specify { expect(setting.value).to eq 'external setting' }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveSetting::Setting, 'with types/casting' do
|
4
|
+
it 'should handle basic types and casting' do
|
5
|
+
s = ActiveSetting::Setting.new(data_type: :integer, raw_value: '6')
|
6
|
+
s.value.should eq 6
|
7
|
+
|
8
|
+
s = ActiveSetting::Setting.new(data_type: :decimal, raw_value: '7.6')
|
9
|
+
s.value.should eq 7.6
|
10
|
+
|
11
|
+
s = ActiveSetting::Setting.new(data_type: :symbol, raw_value: 'hello')
|
12
|
+
s.value.should eq :hello
|
13
|
+
|
14
|
+
s = ActiveSetting::Setting.new(raw_value: 'hello')
|
15
|
+
s.value.should eq 'hello'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should handle boolean types' do
|
19
|
+
s = ActiveSetting::Setting.new(data_type: :boolean, raw_value: '0')
|
20
|
+
s.value.should be false
|
21
|
+
|
22
|
+
s = ActiveSetting::Setting.new(data_type: :boolean, raw_value: 'false')
|
23
|
+
s.value.should be false
|
24
|
+
|
25
|
+
s = ActiveSetting::Setting.new(data_type: :boolean, raw_value: '1')
|
26
|
+
s.value.should be true
|
27
|
+
|
28
|
+
s = ActiveSetting::Setting.new(data_type: :boolean, raw_value: 'true')
|
29
|
+
s.value.should be true
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should handle multi value types including subvalue types and handle spacing' do
|
33
|
+
s = ActiveSetting::Setting.new(data_type: :csv, subtype: :integer, raw_value: '1,2,3')
|
34
|
+
s.value.should eq [1, 2, 3]
|
35
|
+
|
36
|
+
s = ActiveSetting::Setting.new(data_type: :csv, subtype: :symbol, raw_value: 'first, second')
|
37
|
+
s.value.should eq [:first, :second]
|
38
|
+
|
39
|
+
s = ActiveSetting::Setting.new(data_type: :hash, raw_value: 'a:1 , b : 2')
|
40
|
+
s.value.should eq(a: '1', b: '2')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe ActiveSetting::Setting, 'when having options' do
|
45
|
+
it 'should format the options in the right type' do
|
46
|
+
s = ActiveSetting::Setting.new(options: 'easy normal hard')
|
47
|
+
s.options.should eq %w(easy normal hard)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should format the options by key,value when object options' do
|
51
|
+
first = double(id: '1', name: 'First')
|
52
|
+
second = double(id: '2', name: 'Second')
|
53
|
+
s = ActiveSetting::Setting.new
|
54
|
+
s.objects_from_collection([first, second], :name, :id).should eq [%w(First 1), %w(Second 2)]
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should not cache object options' do
|
58
|
+
class Model
|
59
|
+
attr_accessor :id, :name
|
60
|
+
|
61
|
+
def self.objects
|
62
|
+
@objects ||= []
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.all
|
66
|
+
objects
|
67
|
+
end
|
68
|
+
|
69
|
+
class << self
|
70
|
+
attr_writer :objects
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
s = ActiveSetting::Setting.new(object_options: 'Model.all id name')
|
75
|
+
s.options.should eq []
|
76
|
+
first = double(id: 1, name: 'First')
|
77
|
+
Model.objects = [first]
|
78
|
+
s.options.should eq [[1, 'First']]
|
79
|
+
end
|
80
|
+
end
|
data/spec/settings.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
---
|
2
|
+
settings:
|
3
|
+
general_category:
|
4
|
+
maximum_percent:
|
5
|
+
default: 50
|
6
|
+
type: integer
|
7
|
+
description: The minimum percentage to pass
|
8
|
+
difficulty:
|
9
|
+
options: 'easy normal hard'
|
10
|
+
product_ids:
|
11
|
+
type: csv
|
12
|
+
subtype: integer
|
13
|
+
default: '1,2,3'
|
14
|
+
testing:
|
15
|
+
type: boolean
|
16
|
+
default: 'true'
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper.rb"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'bundler/setup'
|
10
|
+
require 'support/coverage_loader'
|
11
|
+
|
12
|
+
require 'active_setting'
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
16
|
+
config.run_all_when_everything_filtered = true
|
17
|
+
config.filter_run :focus
|
18
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
MINIMUM_COVERAGE = 90
|
2
|
+
|
3
|
+
unless ENV['COVERAGE'] == 'off'
|
4
|
+
require 'simplecov'
|
5
|
+
require 'simplecov-rcov'
|
6
|
+
require 'coveralls'
|
7
|
+
Coveralls.wear!
|
8
|
+
|
9
|
+
SimpleCov.formatters = [
|
10
|
+
SimpleCov::Formatter::RcovFormatter,
|
11
|
+
Coveralls::SimpleCov::Formatter
|
12
|
+
]
|
13
|
+
SimpleCov.start do
|
14
|
+
add_filter '/vendor/'
|
15
|
+
add_filter '/spec/'
|
16
|
+
add_group 'lib', 'lib'
|
17
|
+
end
|
18
|
+
SimpleCov.at_exit do
|
19
|
+
SimpleCov.result.format!
|
20
|
+
percent = SimpleCov.result.covered_percent
|
21
|
+
unless percent >= MINIMUM_COVERAGE
|
22
|
+
puts "Coverage must be above #{MINIMUM_COVERAGE}%. It is #{"%.2f" % percent}%"
|
23
|
+
Kernel.exit(1)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_setting
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Noack
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-06-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.4'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.4'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov-rcov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: coveralls
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: travis
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: See README for full details on how to install, use, etc.
|
126
|
+
email: support@travellink.com.au
|
127
|
+
executables: []
|
128
|
+
extensions: []
|
129
|
+
extra_rdoc_files: []
|
130
|
+
files:
|
131
|
+
- ".gitignore"
|
132
|
+
- ".hound.yml"
|
133
|
+
- ".rspec"
|
134
|
+
- ".rubocop.yml"
|
135
|
+
- ".ruby-style.yml"
|
136
|
+
- ".ruby-version"
|
137
|
+
- ".travis.yml"
|
138
|
+
- Gemfile
|
139
|
+
- README.md
|
140
|
+
- Rakefile
|
141
|
+
- active_setting.gemspec
|
142
|
+
- lib/active_setting.rb
|
143
|
+
- lib/active_setting/loader.rb
|
144
|
+
- lib/active_setting/setting.rb
|
145
|
+
- lib/active_setting/version.rb
|
146
|
+
- spec/loader_spec.rb
|
147
|
+
- spec/setting_spec.rb
|
148
|
+
- spec/settings.yml
|
149
|
+
- spec/spec_helper.rb
|
150
|
+
- spec/support/coverage_loader.rb
|
151
|
+
homepage: http://github.com/sealink/active_setting
|
152
|
+
licenses:
|
153
|
+
- MIT
|
154
|
+
metadata: {}
|
155
|
+
post_install_message:
|
156
|
+
rdoc_options: []
|
157
|
+
require_paths:
|
158
|
+
- lib
|
159
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
160
|
+
requirements:
|
161
|
+
- - ">="
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: '0'
|
164
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
|
+
requirements:
|
166
|
+
- - ">="
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: '0'
|
169
|
+
requirements: []
|
170
|
+
rubyforge_project:
|
171
|
+
rubygems_version: 2.5.1
|
172
|
+
signing_key:
|
173
|
+
specification_version: 4
|
174
|
+
summary: Store active_settings of various data types
|
175
|
+
test_files:
|
176
|
+
- spec/loader_spec.rb
|
177
|
+
- spec/setting_spec.rb
|
178
|
+
- spec/settings.yml
|
179
|
+
- spec/spec_helper.rb
|
180
|
+
- spec/support/coverage_loader.rb
|