smart_kv 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.coveralls.yml +1 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +18 -0
- data/README.md +74 -13
- data/lib/smart_kv.rb +0 -6
- data/lib/smart_kv/register.rb +11 -1
- data/lib/smart_kv/version.rb +1 -1
- data/smart_kv.gemspec +1 -1
- metadata +5 -5
- data/lib/smart_kv/macro.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 420ce0e7d38260c55c3727e37875a5d0874c500ec3c47c402b309a3d026c77ab
|
4
|
+
data.tar.gz: 58c5c54dad2de77d66d64253672a842be8fab34fa744c3d287dfbac34d68acf4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c6a325bdee6c9ce5e70e0384afc79f5d754798077667294f0d672d1ea947438fa1860f1e4fe6f1b5fcb68b7a374a2d135744cc78d4eed1b730b25773ba6a17f
|
7
|
+
data.tar.gz: 70c77c085f843d4f8b8d2e533e7bbe180c4cb9da7f38cc5b4066d891775a22e84e88524cf390ba22c9536da23c1da6148a0c76058996106f70bcfcc3c6aa1ded
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
repo_token: 2GrR1SPa8lXAm5kYn2fqp4N7pJGbvW8rO
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -3,7 +3,15 @@ GEM
|
|
3
3
|
specs:
|
4
4
|
byebug (10.0.2)
|
5
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)
|
6
12
|
diff-lcs (1.3)
|
13
|
+
docile (1.3.1)
|
14
|
+
json (2.1.0)
|
7
15
|
method_source (0.9.2)
|
8
16
|
pry (0.12.2)
|
9
17
|
coderay (~> 1.1.0)
|
@@ -25,12 +33,22 @@ GEM
|
|
25
33
|
diff-lcs (>= 1.2.0, < 2.0)
|
26
34
|
rspec-support (~> 3.8.0)
|
27
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)
|
28
45
|
|
29
46
|
PLATFORMS
|
30
47
|
ruby
|
31
48
|
|
32
49
|
DEPENDENCIES
|
33
50
|
bundler (~> 1.17)
|
51
|
+
coveralls
|
34
52
|
pry (~> 0.12)
|
35
53
|
pry-byebug (~> 3.6)
|
36
54
|
rake (~> 10.0)
|
data/README.md
CHANGED
@@ -1,25 +1,64 @@
|
|
1
1
|
# SmartKv
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.org/styd/smart_kv.svg?branch=master)](https://travis-ci.org/styd/smart_kv)
|
4
|
+
[![Coverage Status](https://coveralls.io/repos/github/styd/smart_kv/badge.svg?branch=master)](https://coveralls.io/github/styd/smart_kv?branch=master)
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/smart_kv.svg)](https://rubygems.org/gems/smart_kv)
|
4
6
|
|
5
|
-
Best practice of writing configurations by strictly allowing and requiring keys.
|
7
|
+
Best practice of writing options or configurations by strictly allowing and requiring keys.
|
6
8
|
|
7
|
-
It doesn't have to be
|
9
|
+
It doesn't have to be options or configurations.
|
8
10
|
You can use it for strict request body or other use cases too.
|
9
11
|
|
10
|
-
##
|
12
|
+
## Background
|
11
13
|
|
12
|
-
|
14
|
+
Have you ever used ruby options like this:
|
13
15
|
|
14
16
|
```ruby
|
15
|
-
|
17
|
+
# this example is for rails
|
18
|
+
d = DateTime.now
|
19
|
+
e = d.change(hour: 1, minute: 5)
|
16
20
|
```
|
17
21
|
|
18
|
-
|
22
|
+
and then move on with your life.. until you realize that the code doesn't behave as you expected it to behave.
|
23
|
+
But why? Everything looks fine, right? Yes, it does look fine.. but it's not fine.
|
19
24
|
|
20
|
-
|
25
|
+
So, what's the problem?
|
26
|
+
The problem was the option key `:minute` was not recognized.
|
27
|
+
Eh? :confused:
|
28
|
+
Why didn't it tell me if it was not recognized?
|
29
|
+
|
30
|
+
I wish that too.
|
31
|
+
But `Hash` has a default value of `nil` if key is not found (same thing applies to `OpenStruct`) - so, it will not raise error -
|
32
|
+
and most developers won't bother checking each options' key made by the users of the library or method.
|
21
33
|
|
22
|
-
|
34
|
+
If only the source of the `DateTime#change` method starts like this:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
# this class can be defined on its own file
|
38
|
+
class ChangeOptions < SmartKv
|
39
|
+
optional :nsec, :usec, :year, :month, :day, :hour, :min, :sec, :offset, :start
|
40
|
+
end
|
41
|
+
|
42
|
+
class DateTime
|
43
|
+
...
|
44
|
+
def change(options)
|
45
|
+
options = ChangeOptions.new(options)
|
46
|
+
...
|
47
|
+
end
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
So, when you do this `d.change(hour: 1, minute: 5)`, it will yell:
|
52
|
+
|
53
|
+
```
|
54
|
+
NotImplementedError: unrecognized key(s): `:minute' in ChangeOptions
|
55
|
+
```
|
56
|
+
|
57
|
+
Well, this is better. But, how do you know all the right options?
|
58
|
+
Type: `ChangeOptions.optional_keys` and `ChangeOptions.required_keys`.
|
59
|
+
|
60
|
+
|
61
|
+
## More Usage Example
|
23
62
|
|
24
63
|
```ruby
|
25
64
|
class Config < SmartKv
|
@@ -31,7 +70,9 @@ Config.new({some_key: "val"})
|
|
31
70
|
```
|
32
71
|
|
33
72
|
This will complain that you're not using the `:second key`.
|
34
|
-
|
73
|
+
If you add another key that is not recognized, it will complain too.
|
74
|
+
If there is a key that you don't always use but want it to be recognized, mark it as `optional`.
|
75
|
+
|
35
76
|
|
36
77
|
### Inheritable
|
37
78
|
|
@@ -45,6 +86,7 @@ ChildConfig.new({first_key: "val", second_key: "val 2"})
|
|
45
86
|
|
46
87
|
This will also complain that you're not using the `:some_key`.
|
47
88
|
|
89
|
+
|
48
90
|
### Directly callable
|
49
91
|
|
50
92
|
Whatever given as input is callable directly.
|
@@ -57,6 +99,7 @@ c2 = Config.new(OpenStruct.new({some_key: "val", second_key: "val 2"}))
|
|
57
99
|
c2.second_key
|
58
100
|
```
|
59
101
|
|
102
|
+
|
60
103
|
### Override callable object
|
61
104
|
|
62
105
|
You can change the callable object to any class that accepts hash as input of its new class method.
|
@@ -71,9 +114,10 @@ c = Convertable.new({abcd: 123})
|
|
71
114
|
c.abcd #=> 123
|
72
115
|
```
|
73
116
|
|
74
|
-
### Not using it for config
|
75
117
|
|
76
|
-
|
118
|
+
### Not using it for options or configs?
|
119
|
+
|
120
|
+
You can choose not to use it for options or configs. Maybe for strict request body keys?
|
77
121
|
|
78
122
|
```ruby
|
79
123
|
class PostBody < SmartKv
|
@@ -84,22 +128,39 @@ end
|
|
84
128
|
request.set_form_data(PostBody.new({app_key: "abc", secret_key: "def"}))
|
85
129
|
```
|
86
130
|
|
131
|
+
|
132
|
+
## Installation
|
133
|
+
|
134
|
+
Add this line to your application's Gemfile:
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
gem 'smart_kv'
|
138
|
+
```
|
139
|
+
|
140
|
+
And then execute:
|
141
|
+
|
142
|
+
$ bundle
|
143
|
+
|
144
|
+
|
87
145
|
## Coming Soon
|
88
146
|
|
89
|
-
- [ ] Make it serializable
|
90
147
|
- [X] Convertable from hash (as input) to OpenStruct (the resulting object) or another object and vice versa
|
91
|
-
- [ ]
|
148
|
+
- [ ] Suggests corrections for unrecognized keys using DidYouMean (and maybe change the spell checking threshold?)
|
92
149
|
- [ ] Support nested/deep key value object as input
|
93
150
|
- [ ] Make some nested keys from the same parent key required and some others optional
|
151
|
+
- [ ] Accept config file (e.g. `json`, `yaml`, etc.) or file path as input
|
152
|
+
|
94
153
|
|
95
154
|
## Contributing
|
96
155
|
|
97
156
|
Bug reports and pull requests are welcome on GitHub at https://github.com/styd/smart_kv. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
98
157
|
|
158
|
+
|
99
159
|
## License
|
100
160
|
|
101
161
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
102
162
|
|
163
|
+
|
103
164
|
## Code of Conduct
|
104
165
|
|
105
166
|
Everyone interacting in the SmartKv project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/styd/smart_kv/blob/master/CODE_OF_CONDUCT.md).
|
data/lib/smart_kv.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
require "smart_kv/version"
|
2
2
|
require "smart_kv/register"
|
3
|
-
require "smart_kv/macro"
|
4
3
|
|
5
4
|
SmartKvInitializationError = Class.new(StandardError)
|
6
5
|
|
7
6
|
class SmartKv
|
8
7
|
extend Register
|
9
|
-
extend Macro
|
10
8
|
|
11
9
|
attr_reader :object_class
|
12
10
|
|
@@ -16,10 +14,6 @@ class SmartKv
|
|
16
14
|
@object_class = object_class || kv.class
|
17
15
|
@kv = kv.dup
|
18
16
|
|
19
|
-
if @object_class.respond_to?(:members) && @object_class.members != @kv.to_h.keys
|
20
|
-
raise ArgumentError, "#{ @object_class } struct size differs"
|
21
|
-
end
|
22
|
-
|
23
17
|
hash = kv.to_h.dup
|
24
18
|
missing_keys = required_keys - hash.keys
|
25
19
|
unless missing_keys.empty?
|
data/lib/smart_kv/register.rb
CHANGED
@@ -2,6 +2,8 @@ module SmartKv::Register
|
|
2
2
|
def required(*args)
|
3
3
|
@required ||= superclass == SmartKv ? Set.new : superclass.required_keys.dup
|
4
4
|
@required += args
|
5
|
+
@optional -= @required if @optional
|
6
|
+
@required
|
5
7
|
end
|
6
8
|
|
7
9
|
def required_keys
|
@@ -11,7 +13,7 @@ module SmartKv::Register
|
|
11
13
|
def optional(*args)
|
12
14
|
@optional ||= superclass == SmartKv ? Set.new : superclass.optional_keys.dup
|
13
15
|
@optional += args
|
14
|
-
@required -= @optional
|
16
|
+
@required -= @optional if @required
|
15
17
|
@optional
|
16
18
|
end
|
17
19
|
|
@@ -22,4 +24,12 @@ module SmartKv::Register
|
|
22
24
|
def new(*args)
|
23
25
|
super(@required.to_a, @optional.to_a, @callable_as, *args)
|
24
26
|
end
|
27
|
+
|
28
|
+
def callable_as(klass)
|
29
|
+
@callable_as = superclass == SmartKv ? klass : superclass.callable_class
|
30
|
+
end
|
31
|
+
|
32
|
+
def callable_class
|
33
|
+
@callable_as
|
34
|
+
end
|
25
35
|
end
|
data/lib/smart_kv/version.rb
CHANGED
data/smart_kv.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["a.styd@yahoo.com"]
|
11
11
|
|
12
12
|
spec.summary = %q{Smart checks for your key value objects.}
|
13
|
-
spec.description = %q{Best practice of writing configurations by strictly allowing and requiring keys.}
|
13
|
+
spec.description = %q{Best practice of writing options or configurations by strictly allowing and requiring keys.}
|
14
14
|
spec.homepage = "https://github.com/styd/smart_kv"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
metadata
CHANGED
@@ -1,23 +1,24 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_kv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adrian Setyadi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description: Best practice of writing configurations by strictly allowing
|
14
|
-
keys.
|
13
|
+
description: Best practice of writing options or configurations by strictly allowing
|
14
|
+
and requiring keys.
|
15
15
|
email:
|
16
16
|
- a.styd@yahoo.com
|
17
17
|
executables: []
|
18
18
|
extensions: []
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
|
+
- ".coveralls.yml"
|
21
22
|
- ".gitignore"
|
22
23
|
- ".rspec"
|
23
24
|
- ".travis.yml"
|
@@ -30,7 +31,6 @@ files:
|
|
30
31
|
- bin/console
|
31
32
|
- bin/setup
|
32
33
|
- lib/smart_kv.rb
|
33
|
-
- lib/smart_kv/macro.rb
|
34
34
|
- lib/smart_kv/register.rb
|
35
35
|
- lib/smart_kv/version.rb
|
36
36
|
- smart_kv.gemspec
|