smart_kv 0.1.4 → 0.2.3
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 +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +1 -0
- data/Gemfile +1 -14
- data/README.md +5 -3
- data/lib/smart_kv.rb +19 -7
- data/lib/smart_kv/did_you_mean.rb +7 -0
- data/lib/smart_kv/errors.rb +13 -0
- data/lib/smart_kv/version.rb +1 -1
- data/smart_kv.gemspec +8 -0
- metadata +103 -4
- data/Gemfile.lock +0 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 18d8a80239ecbfcc6b948865773902b355f964763d1c48970abdd15cd0fd776b
|
4
|
+
data.tar.gz: 10b66b81f593f48ddbcfc3d9d2dcf53869c018b30ea2253e14b399973c12abb4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5af3e66863206152ad3c01518e383ee02e377b8e26be7706986c7761831e7d0ed1a6fa08f8284cb6707fddb38e982b6cb120d3f020c47b489667f08755b51bc5
|
7
|
+
data.tar.gz: 8d9b376526c263a57d7bd8691ec847aeeca35a8b32e72098d763d965c8e3d707345b0c65495ccafc4d3d2b03e9048cb463629c0a4ec85b7a623c34d370bcffeb
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -2,17 +2,4 @@ source "https://rubygems.org"
|
|
2
2
|
|
3
3
|
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
4
4
|
|
5
|
-
|
6
|
-
gem "pry", "~> 0.12"
|
7
|
-
gem "pry-byebug", "~> 3.6"
|
8
|
-
end
|
9
|
-
|
10
|
-
group :test do
|
11
|
-
gem "rspec", "~> 3.0"
|
12
|
-
gem 'coveralls', require: false
|
13
|
-
end
|
14
|
-
|
15
|
-
group :development do
|
16
|
-
gem "bundler", "~> 1.17"
|
17
|
-
gem "rake", "~> 10.0"
|
18
|
-
end
|
5
|
+
gemspec
|
data/README.md
CHANGED
@@ -28,8 +28,10 @@ Eh? :confused:
|
|
28
28
|
Why didn't it tell me if it was not recognized?
|
29
29
|
|
30
30
|
I wish that too.
|
31
|
-
But `Hash` has a default value of `nil` if key is not found (same thing applies to `OpenStruct`)
|
32
|
-
|
31
|
+
But `Hash` has a default value of `nil` if key is not found (same thing applies to `OpenStruct`).
|
32
|
+
So, it will fail gracefully even if an option is actually required, unless the developer uses `#fetch` instead of `#[]`.
|
33
|
+
Even if the developer uses `#fetch` for required keys, it doesn't actually check if there are foreign keys input.
|
34
|
+
Also, most developers won't bother checking each options' key made by the users of the library or method.
|
33
35
|
|
34
36
|
If only the source of the `DateTime#change` method starts like this:
|
35
37
|
|
@@ -145,7 +147,7 @@ And then execute:
|
|
145
147
|
## Coming Soon
|
146
148
|
|
147
149
|
- [X] Convertable from hash (as input) to OpenStruct (the resulting object) or another object and vice versa
|
148
|
-
- [
|
150
|
+
- [X] Suggests corrections for unrecognized keys using DidYouMean
|
149
151
|
- [ ] Support nested/deep key value object as input
|
150
152
|
- [ ] Make some nested keys from the same parent key required and some others optional
|
151
153
|
- [ ] Accept config file (e.g. `json`, `yaml`, etc.) or file path as input
|
data/lib/smart_kv.rb
CHANGED
@@ -1,7 +1,14 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
def has_did_you_mean_key_error?
|
2
|
+
!ENV['TRAVIS'] && Gem::Version.new(RUBY_VERSION) > Gem::Version.new("2.5.0") && defined?(DidYouMean)
|
3
|
+
end
|
4
|
+
|
5
|
+
require_relative "smart_kv/version"
|
6
|
+
require_relative "smart_kv/register"
|
7
|
+
require_relative "smart_kv/errors"
|
3
8
|
|
4
|
-
|
9
|
+
if has_did_you_mean_key_error?
|
10
|
+
require_relative "smart_kv/did_you_mean"
|
11
|
+
end
|
5
12
|
|
6
13
|
class SmartKv
|
7
14
|
extend Register
|
@@ -14,18 +21,23 @@ class SmartKv
|
|
14
21
|
@object_class = object_class || kv.class
|
15
22
|
@kv = kv.dup
|
16
23
|
|
17
|
-
hash = kv.to_h
|
24
|
+
hash = kv.to_h
|
18
25
|
missing_keys = required_keys - hash.keys
|
19
26
|
unless missing_keys.empty?
|
20
|
-
raise KeyError, "missing required key(s): #{missing_keys.map{|k|
|
27
|
+
raise KeyError, "missing required key(s): #{missing_keys.map{|k| k.to_sym.inspect }.join(', ')} in #{self.class}"
|
21
28
|
end
|
22
29
|
|
23
30
|
unrecognized_keys = hash.keys - required_keys - optional_keys
|
24
31
|
unless unrecognized_keys.empty?
|
25
|
-
|
32
|
+
key = unrecognized_keys.first
|
33
|
+
raise KeyError.new("key not found: #{key.inspect}.", key: key, receiver: (keys - hash.keys).map {|k| [k, nil] }.to_h)
|
26
34
|
end
|
27
35
|
end
|
28
36
|
|
37
|
+
def keys
|
38
|
+
Array(self.class.required) + Array(self.class.optional)
|
39
|
+
end
|
40
|
+
|
29
41
|
def method_missing(m, *args)
|
30
42
|
@object ||= if @object_class == Struct
|
31
43
|
Struct.new(*@kv.to_h.keys).new(*@kv.to_h.values)
|
@@ -43,7 +55,7 @@ protected
|
|
43
55
|
|
44
56
|
def prevent_direct_instantiation
|
45
57
|
if self.class == SmartKv
|
46
|
-
raise
|
58
|
+
raise InitializationError, "only subclass of SmartConfig can be instantiated"
|
47
59
|
end
|
48
60
|
end
|
49
61
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class SmartKv
|
2
|
+
InitializationError = Class.new(StandardError)
|
3
|
+
|
4
|
+
class KeyError < ::StandardError
|
5
|
+
attr_reader :key, :receiver
|
6
|
+
|
7
|
+
def initialize(message, key: nil, receiver: {})
|
8
|
+
@key = key
|
9
|
+
@receiver = receiver
|
10
|
+
super(message)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/smart_kv/version.rb
CHANGED
data/smart_kv.gemspec
CHANGED
@@ -22,4 +22,12 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.bindir = "exe"
|
23
23
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
24
|
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
27
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
29
|
+
spec.add_development_dependency "coveralls"
|
30
|
+
spec.add_development_dependency "pry", "~> 0.12"
|
31
|
+
spec.add_development_dependency "pry-byebug", "~> 3.6"
|
32
|
+
spec.add_development_dependency "pry-doc"
|
25
33
|
end
|
metadata
CHANGED
@@ -1,15 +1,113 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_kv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adrian Setyadi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
12
|
-
dependencies:
|
11
|
+
date: 2019-02-24 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: '1.17'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.17'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.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.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: coveralls
|
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: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.12'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.12'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry-byebug
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.6'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.6'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry-doc
|
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'
|
13
111
|
description: Best practice of writing options or configurations by strictly allowing
|
14
112
|
and requiring keys.
|
15
113
|
email:
|
@@ -24,13 +122,14 @@ files:
|
|
24
122
|
- ".travis.yml"
|
25
123
|
- CODE_OF_CONDUCT.md
|
26
124
|
- Gemfile
|
27
|
-
- Gemfile.lock
|
28
125
|
- LICENSE.txt
|
29
126
|
- README.md
|
30
127
|
- Rakefile
|
31
128
|
- bin/console
|
32
129
|
- bin/setup
|
33
130
|
- lib/smart_kv.rb
|
131
|
+
- lib/smart_kv/did_you_mean.rb
|
132
|
+
- lib/smart_kv/errors.rb
|
34
133
|
- lib/smart_kv/register.rb
|
35
134
|
- lib/smart_kv/version.rb
|
36
135
|
- smart_kv.gemspec
|
data/Gemfile.lock
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
GEM
|
2
|
-
remote: https://rubygems.org/
|
3
|
-
specs:
|
4
|
-
byebug (10.0.2)
|
5
|
-
coderay (1.1.2)
|
6
|
-
coveralls (0.8.22)
|
7
|
-
json (>= 1.8, < 3)
|
8
|
-
simplecov (~> 0.16.1)
|
9
|
-
term-ansicolor (~> 1.3)
|
10
|
-
thor (~> 0.19.4)
|
11
|
-
tins (~> 1.6)
|
12
|
-
diff-lcs (1.3)
|
13
|
-
docile (1.3.1)
|
14
|
-
json (2.1.0)
|
15
|
-
method_source (0.9.2)
|
16
|
-
pry (0.12.2)
|
17
|
-
coderay (~> 1.1.0)
|
18
|
-
method_source (~> 0.9.0)
|
19
|
-
pry-byebug (3.6.0)
|
20
|
-
byebug (~> 10.0)
|
21
|
-
pry (~> 0.10)
|
22
|
-
rake (10.5.0)
|
23
|
-
rspec (3.8.0)
|
24
|
-
rspec-core (~> 3.8.0)
|
25
|
-
rspec-expectations (~> 3.8.0)
|
26
|
-
rspec-mocks (~> 3.8.0)
|
27
|
-
rspec-core (3.8.0)
|
28
|
-
rspec-support (~> 3.8.0)
|
29
|
-
rspec-expectations (3.8.2)
|
30
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
31
|
-
rspec-support (~> 3.8.0)
|
32
|
-
rspec-mocks (3.8.0)
|
33
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
34
|
-
rspec-support (~> 3.8.0)
|
35
|
-
rspec-support (3.8.0)
|
36
|
-
simplecov (0.16.1)
|
37
|
-
docile (~> 1.1)
|
38
|
-
json (>= 1.8, < 3)
|
39
|
-
simplecov-html (~> 0.10.0)
|
40
|
-
simplecov-html (0.10.2)
|
41
|
-
term-ansicolor (1.7.0)
|
42
|
-
tins (~> 1.0)
|
43
|
-
thor (0.19.4)
|
44
|
-
tins (1.20.2)
|
45
|
-
|
46
|
-
PLATFORMS
|
47
|
-
ruby
|
48
|
-
|
49
|
-
DEPENDENCIES
|
50
|
-
bundler (~> 1.17)
|
51
|
-
coveralls
|
52
|
-
pry (~> 0.12)
|
53
|
-
pry-byebug (~> 3.6)
|
54
|
-
rake (~> 10.0)
|
55
|
-
rspec (~> 3.0)
|
56
|
-
|
57
|
-
BUNDLED WITH
|
58
|
-
1.17.2
|