setti 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 +15 -0
- data/Rakefile +15 -0
- data/lib/setti.rb +4 -0
- data/lib/setti/indifferent_hash.rb +12 -0
- data/lib/setti/settings.rb +71 -0
- data/lib/setti/version.rb +3 -0
- data/spec/sample.json +19 -0
- data/spec/settings_spec.rb +49 -0
- data/spec/spec_helper.rb +2 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZTg5YzdkZjAyZDkxMzRmNmM4YjE0MTQxODhhNTk3OGM2MmExMzBiNg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ODFmNzAxN2JhYTAwNjcyYTI3MjY3MzNlNTAzOWFlYzgyNTExZjk0Mw==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NWQ2ZWY2NmM3MGQ5ZGYzNTk0YzA4MTE0ZWFhODdjYTE2Y2UwNjBlNmZiNDRl
|
10
|
+
ZDM0ZDBkMDI2MGNkYTlhZjBlYzQ4Zjk5NzExYjQ1NWYyMTc0ZjZlYWU3MTVh
|
11
|
+
Y2U1ZDhkMDE5ZTg5MWRkMTMxODI3ZjNhYTRkYmMzYzM1NTllMDQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YWE2NTNjZjgwMDI5YmExMGE0ZjQ2ODI1NWI3MzBlZTljOWI3YjYxNGM2OWU4
|
14
|
+
NGVlMGEwNDQxYjQzYmM2YjI1NWM4ODJiYWEyYmYwMTRjZGZiOTA2MjJlOTlj
|
15
|
+
ZGY5ODIyNDAyOTZkMThhNWVlZDZiZDNiYTc4OWFmZDZhMDE3ZTM=
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
|
3
|
+
RSpec::Core::RakeTask.new(:spec)
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'rubocop/rake_task'
|
7
|
+
Rubocop::RakeTask.new
|
8
|
+
rescue LoadError
|
9
|
+
desc 'Run RuboCop'
|
10
|
+
task :rubocop do
|
11
|
+
$stderr.puts 'Rubocop is disabled'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
task default: [:spec, :rubocop]
|
data/lib/setti.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'oj'
|
2
|
+
|
3
|
+
module Setti
|
4
|
+
class Settings
|
5
|
+
def initialize(path)
|
6
|
+
assert File.exist?(path), error: "No such file or directory: #{path}"
|
7
|
+
@settings = Oj.load(IO.read(path), mode: :compat)
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate(name, *args, &block)
|
11
|
+
value = lookup_property(name)
|
12
|
+
case args.first
|
13
|
+
when nil then nil_check!(name, value, block)
|
14
|
+
when :number then number_check!(name, value)
|
15
|
+
when :float then float_check!(name, value)
|
16
|
+
when :integer then int_check!(name, value)
|
17
|
+
when :regex then regex_check!(name, value, args.last)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def [](name)
|
22
|
+
with_indifferent_hash lookup_property(name)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def nil_check!(name, value, block)
|
28
|
+
fail "#{name}=#{value} does not comply with the validation" unless block.call(value)
|
29
|
+
end
|
30
|
+
|
31
|
+
def number_check!(name, value)
|
32
|
+
fail "#{name}=#{value} is not a number" unless [Integer, Fixnum, Float].include? value.class
|
33
|
+
end
|
34
|
+
|
35
|
+
def float_check!(name, value)
|
36
|
+
fail "#{name}=#{value} is not a float" unless value.is_a? Float
|
37
|
+
end
|
38
|
+
|
39
|
+
def int_check!(name, value)
|
40
|
+
fail "#{name}=#{value} is not an integer" unless [Integer, Fixnum].include? value.class
|
41
|
+
end
|
42
|
+
|
43
|
+
def regex_check!(name, value, regex)
|
44
|
+
fail "#{name}=#{value} does not match #{regex}" unless value =~ regex
|
45
|
+
end
|
46
|
+
|
47
|
+
def lookup_property(name)
|
48
|
+
if name.is_a?(String) && name.include?('.')
|
49
|
+
lookup_value_dot_path(name)
|
50
|
+
else
|
51
|
+
IndifferentHash[@settings][name]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def lookup_value_dot_path(name)
|
56
|
+
names = name.split('.')
|
57
|
+
names.inject(@settings) do |walker, cur_name|
|
58
|
+
fail "Not found: #{name}" unless walker[cur_name]
|
59
|
+
walker[cur_name]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def assert(condition, options = {})
|
64
|
+
fail options[:error] unless condition
|
65
|
+
end
|
66
|
+
|
67
|
+
def with_indifferent_hash(value)
|
68
|
+
value.is_a?(Hash) ? IndifferentHash[value] : value
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/spec/sample.json
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'setti')
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Setti::Settings do
|
5
|
+
subject { Setti::Settings.new(File.join(File.dirname(__FILE__), 'sample.json')) }
|
6
|
+
|
7
|
+
it 'does load sample config file' do
|
8
|
+
expect { subject }.to_not raise_error
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'does provide dot accessors' do
|
12
|
+
expect(subject['numbers.integers.bad']).to eql('80')
|
13
|
+
expect(subject['numbers.integers.good']).to eql(80)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'does provide hash accessors' do
|
17
|
+
expect(subject['numbers']['integers']['bad']).to eql('80')
|
18
|
+
expect(subject['numbers']['integers']['good']).to eql(80)
|
19
|
+
|
20
|
+
# Symbols and also recursive
|
21
|
+
expect(subject[:numbers][:integers][:bad]).to eql('80')
|
22
|
+
expect(subject[:numbers][:integers][:good]).to eql(80)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'does validate numbers' do
|
26
|
+
expect { subject.validate 'numbers.integers.bad', :number }.to raise_error
|
27
|
+
expect { subject.validate 'numbers.integers.good', :number }.to_not raise_error
|
28
|
+
expect { subject.validate 'numbers.floats.bad', :float }.to raise_error
|
29
|
+
expect { subject.validate 'numbers.floats.good', :float }.to_not raise_error
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'does validate regexes' do
|
33
|
+
expect { subject.validate 'regexes.good', :regex, /^\d[a-zA-Z]{3}$/ }.to_not raise_error
|
34
|
+
expect { subject.validate 'regexes.bad', :regex, /^\d[a-zA-Z]{3}$/ }.to raise_error
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'does validate procs' do
|
38
|
+
expect { subject.validate('procs.true') { |val| val } }.to_not raise_error
|
39
|
+
expect { subject.validate('procs.true') { |val| !val } }.to raise_error
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'Config. file missing' do
|
43
|
+
subject { Setti::Settings.new('foo.json') }
|
44
|
+
|
45
|
+
it 'does raise a ENOENT error' do
|
46
|
+
expect { subject }.to raise_error
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: setti
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- André Dieb Martins
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: oj
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.9'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.3'
|
55
|
+
description: Fast indifferent-access JSON settings framework, validation included.
|
56
|
+
email:
|
57
|
+
- andre.dieb@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- Rakefile
|
63
|
+
- lib/setti.rb
|
64
|
+
- lib/setti/indifferent_hash.rb
|
65
|
+
- lib/setti/settings.rb
|
66
|
+
- lib/setti/version.rb
|
67
|
+
- spec/sample.json
|
68
|
+
- spec/settings_spec.rb
|
69
|
+
- spec/spec_helper.rb
|
70
|
+
homepage: https://github.com/dieb/setti
|
71
|
+
licenses:
|
72
|
+
- MIT
|
73
|
+
metadata: {}
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
requirements: []
|
89
|
+
rubyforge_project:
|
90
|
+
rubygems_version: 2.2.2
|
91
|
+
signing_key:
|
92
|
+
specification_version: 4
|
93
|
+
summary: Settings microframework for ruby applications.
|
94
|
+
test_files:
|
95
|
+
- spec/sample.json
|
96
|
+
- spec/settings_spec.rb
|
97
|
+
- spec/spec_helper.rb
|