ru.Bee 2.1.0 → 2.1.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 +4 -4
- data/lib/rubee/extensions/validatable.rb +45 -6
- data/lib/rubee.rb +1 -1
- data/lib/tests/models/account_model_test.rb +2 -3
- data/lib/tests/models/comment_model_test.rb +47 -5
- data/lib/tests/test.db +0 -0
- data/readme.md +65 -47
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cc6a4fbeb28a460ca66f75ccf1f5c97fe1572f422392f9ee1b72d082e05cb287
|
|
4
|
+
data.tar.gz: f4dbeaf7338af243f6e225a2a798a87de75b001fa4196bed94345d78887ba8ea
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 996510c80521425797e17a1b641d767d6319877e127883692d519457c7573835ae2670a8ed17950f302b1934a0aae1270d8b065acfee079341935ddb8964a26f
|
|
7
|
+
data.tar.gz: 75a8ab899d3c98fd492a30ec5501982526318387c9214b78ebdf57ec2c39a91778268283db82cbeb5ae9072aa4c62507b1d175423e7f86beec892cddfea0bb90
|
|
@@ -31,44 +31,73 @@ module Rubee
|
|
|
31
31
|
@optional = false
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
def required(
|
|
34
|
+
def required(error_message = nil)
|
|
35
35
|
value = @instance.send(@attribute)
|
|
36
|
+
|
|
37
|
+
error_hash = assemble_error_hash(error_message, :required, attribute: @attribute)
|
|
36
38
|
if value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
|
37
39
|
@state.add_error(@attribute, error_hash)
|
|
38
40
|
end
|
|
41
|
+
|
|
39
42
|
self
|
|
40
43
|
end
|
|
41
44
|
|
|
42
45
|
def optional(*)
|
|
43
46
|
@optional = true
|
|
47
|
+
|
|
44
48
|
self
|
|
45
49
|
end
|
|
46
50
|
|
|
47
|
-
def
|
|
48
|
-
|
|
51
|
+
def attribute
|
|
52
|
+
self
|
|
53
|
+
end
|
|
49
54
|
|
|
55
|
+
def type(expected_class, error_message = nil)
|
|
56
|
+
return self if @state.has_errors_for?(@attribute)
|
|
50
57
|
value = @instance.send(@attribute)
|
|
51
58
|
return self if @optional && value.nil?
|
|
52
59
|
|
|
60
|
+
error_hash = assemble_error_hash(error_message, :type, class: expected_class)
|
|
53
61
|
unless value.is_a?(expected_class)
|
|
54
62
|
@state.add_error(@attribute, error_hash)
|
|
55
63
|
end
|
|
64
|
+
|
|
56
65
|
self
|
|
57
66
|
end
|
|
58
67
|
|
|
59
|
-
def condition(handler, error_message)
|
|
68
|
+
def condition(handler, error_message = nil)
|
|
60
69
|
return self if @state.has_errors_for?(@attribute)
|
|
61
70
|
value = @instance.send(@attribute)
|
|
62
71
|
return self if @optional && value.nil?
|
|
63
72
|
|
|
73
|
+
error_hash = assemble_error_hash(error_message, :condition)
|
|
64
74
|
if handler.respond_to?(:call)
|
|
65
|
-
@state.add_error(@attribute,
|
|
75
|
+
@state.add_error(@attribute, error_hash) unless handler.call
|
|
66
76
|
else
|
|
67
77
|
@instance.send(handler)
|
|
68
78
|
end
|
|
69
79
|
|
|
70
80
|
self
|
|
71
81
|
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
def assemble_error_hash(error_message, error_type, **options)
|
|
86
|
+
error_message ||= default_message(error_type, **options)
|
|
87
|
+
if error_message.is_a?(String)
|
|
88
|
+
error_message = { message: error_message }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
error_message
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def default_message(type, **options)
|
|
95
|
+
{
|
|
96
|
+
condition: "condition is not met",
|
|
97
|
+
required: "attribute '#{options[:attribute]}' is required",
|
|
98
|
+
type: "attribute must be #{options[:class]}",
|
|
99
|
+
}[type]
|
|
100
|
+
end
|
|
72
101
|
end
|
|
73
102
|
|
|
74
103
|
def self.included(base)
|
|
@@ -102,7 +131,17 @@ module Rubee
|
|
|
102
131
|
|
|
103
132
|
def run_validations
|
|
104
133
|
@__validation_state = State.new
|
|
105
|
-
self.class
|
|
134
|
+
if (block = self.class.validation_block)
|
|
135
|
+
instance_exec(&block)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def subject
|
|
140
|
+
@__validation_state.instance
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def attribute(name)
|
|
144
|
+
RuleChain.new(self, name, @__validation_state).attribute
|
|
106
145
|
end
|
|
107
146
|
|
|
108
147
|
def required(attribute, options)
|
data/lib/rubee.rb
CHANGED
|
@@ -17,7 +17,7 @@ module Rubee
|
|
|
17
17
|
CSS_DIR = File.join(APP_ROOT, LIB, 'css') unless defined?(CSS_DIR)
|
|
18
18
|
ROOT_PATH = File.expand_path(File.join(__dir__, '..')) unless defined?(ROOT_PATH)
|
|
19
19
|
|
|
20
|
-
VERSION = '2.1.
|
|
20
|
+
VERSION = '2.1.1'
|
|
21
21
|
|
|
22
22
|
require_relative 'rubee/router'
|
|
23
23
|
require_relative 'rubee/logger'
|
|
@@ -18,9 +18,8 @@ describe 'Account model' do
|
|
|
18
18
|
|
|
19
19
|
describe '#validate_before_persist' do
|
|
20
20
|
it 'rasies error if account is not valid' do
|
|
21
|
-
Account.validate do
|
|
22
|
-
|
|
23
|
-
.required(:addres, required: "address is required")
|
|
21
|
+
Account.validate do
|
|
22
|
+
required(:addres, required: "address is required")
|
|
24
23
|
.type(String, type: "address must be string")
|
|
25
24
|
end
|
|
26
25
|
Account.validate_before_persist!
|
|
@@ -47,17 +47,17 @@ describe 'Comment model' do
|
|
|
47
47
|
|
|
48
48
|
describe 'validatable' do
|
|
49
49
|
def include_and_validate(required: true)
|
|
50
|
-
# Comment.include(Rubee::Validatable)
|
|
51
50
|
required_or_optional = required ? :required : :optional
|
|
52
|
-
required_or_optional_args = required ? [
|
|
53
|
-
Comment.validate do
|
|
54
|
-
|
|
51
|
+
required_or_optional_args = required ? [required: "text filed is required"] : []
|
|
52
|
+
Comment.validate do
|
|
53
|
+
attribute(:text).send(
|
|
55
54
|
required_or_optional, *required_or_optional_args
|
|
56
55
|
)
|
|
57
56
|
.type(String, type: "text field must be string")
|
|
58
|
-
.condition(proc {
|
|
57
|
+
.condition(proc { text.length > 4 }, { length: "text length must be greater than 4" })
|
|
59
58
|
end
|
|
60
59
|
end
|
|
60
|
+
|
|
61
61
|
it 'is valid' do
|
|
62
62
|
include_and_validate
|
|
63
63
|
comment = Comment.new(text: 'test it as valid')
|
|
@@ -180,5 +180,47 @@ describe 'Comment model' do
|
|
|
180
180
|
assert_equal('testerter', comment.text)
|
|
181
181
|
end
|
|
182
182
|
end
|
|
183
|
+
|
|
184
|
+
describe 'default errors as error' do
|
|
185
|
+
it 'assembles error hash' do
|
|
186
|
+
Comment.validate do
|
|
187
|
+
attribute(:text).required.type(String).condition(-> { text.length > 4 })
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
comment = Comment.new(text: 'test')
|
|
191
|
+
_(comment.valid?).must_equal(false)
|
|
192
|
+
_(comment.errors[:text]).must_equal({ message: "condition is not met" })
|
|
193
|
+
|
|
194
|
+
comment = Comment.new(text: 123)
|
|
195
|
+
_(comment.valid?).must_equal(false)
|
|
196
|
+
_(comment.errors[:text]).must_equal({ message: "attribute must be String" })
|
|
197
|
+
|
|
198
|
+
comment = Comment.new(user_id: User.last)
|
|
199
|
+
_(comment.valid?).must_equal(false)
|
|
200
|
+
_(comment.errors[:text]).must_equal({ message: "attribute 'text' is required" })
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
describe 'message instead hash as error' do
|
|
205
|
+
it 'assembles error hash' do
|
|
206
|
+
Comment.validate do
|
|
207
|
+
attribute(:text)
|
|
208
|
+
.required("Text is a mandatory field").type(String, "Text must be a string")
|
|
209
|
+
.condition(-> { text.length > 4 }, "Text length must be greater than 4")
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
comment = Comment.new(text: 'test')
|
|
213
|
+
_(comment.valid?).must_equal(false)
|
|
214
|
+
_(comment.errors[:text]).must_equal({ message: "Text length must be greater than 4" })
|
|
215
|
+
|
|
216
|
+
comment = Comment.new(text: 123)
|
|
217
|
+
_(comment.valid?).must_equal(false)
|
|
218
|
+
_(comment.errors[:text]).must_equal({ message: "Text must be a string" })
|
|
219
|
+
|
|
220
|
+
comment = Comment.new(user_id: User.last)
|
|
221
|
+
_(comment.valid?).must_equal(false)
|
|
222
|
+
_(comment.errors[:text]).must_equal({ message: "Text is a mandatory field" })
|
|
223
|
+
end
|
|
224
|
+
end
|
|
183
225
|
end
|
|
184
226
|
end
|
data/lib/tests/test.db
CHANGED
|
Binary file
|
data/readme.md
CHANGED
|
@@ -881,70 +881,88 @@ class Foo
|
|
|
881
881
|
@age = age
|
|
882
882
|
end
|
|
883
883
|
|
|
884
|
-
validate do
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
.
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
.required(:age, required: 'Age is required')
|
|
892
|
-
.type(Integer, type: 'must be an integer')
|
|
893
|
-
.condition(->{ foo.age > 18 }, age: 'You must be at least 18 years old')
|
|
884
|
+
validate do
|
|
885
|
+
attribute(:name).required.type(String).condition(->{ name.length > 2 })
|
|
886
|
+
|
|
887
|
+
attribute(:age)
|
|
888
|
+
.required('Age is a manadatory field')
|
|
889
|
+
.type(Integer, error_message: 'Must be an integerRRRRRRrrr!')
|
|
890
|
+
.condition(->{ age > 18 }, fancy_error: 'You must be at least 18 years old, dude!')
|
|
894
891
|
end
|
|
895
892
|
end
|
|
896
893
|
```
|
|
894
|
+
Then we can evaluate it in the ru.Bee console
|
|
897
895
|
```bash
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
896
|
+
=> #<Proc:0x000000010d389d80 (irb):32>
|
|
897
|
+
irb(main):041> Foo.new("Test", 20)
|
|
898
|
+
=> #<Foo:0x000000010d383fc0 @__validation_state=#<Rubee::Validatable::State:0x000000010d383de0 @errors={}, @valid=true>, @age=20, @name="Test">
|
|
899
|
+
irb(main):042> Foo.new("Test", 1)
|
|
900
|
+
=>
|
|
901
|
+
#<Foo:0x000000010ce61c40
|
|
902
|
+
@__validation_state=#<Rubee::Validatable::State:0x000000010ce61bc8 @errors={age: {fancy_error: "You must be at least 18 years old, dude!"}}, @valid=false>,
|
|
903
|
+
@age=1,
|
|
904
|
+
@name="Test">
|
|
905
|
+
irb(main):043> Foo.new("Test", nil)
|
|
906
|
+
=>
|
|
907
|
+
#<Foo:0x000000010c46f200
|
|
908
|
+
@__validation_state=#<Rubee::Validatable::State:0x000000010c46f070 @errors={age: {message: "Age is a manadatory field"}}, @valid=false>,
|
|
909
|
+
@age=nil,
|
|
910
|
+
@name="Test">
|
|
911
|
+
irb(main):044> Foo.new("Te", 20)
|
|
912
|
+
=>
|
|
913
|
+
#<Foo:0x000000010cfe9270
|
|
914
|
+
@__validation_state=#<Rubee::Validatable::State:0x000000010cfe91f8 @errors={name: {message: "condition is not met"}}, @valid=false>,
|
|
915
|
+
@age=20,
|
|
916
|
+
@name="Te">
|
|
917
|
+
irb(main):045> foo = Foo.new("Joe", "wrong")
|
|
918
|
+
=>
|
|
919
|
+
#<Foo:0x000000010d32eb38
|
|
920
|
+
...
|
|
921
|
+
irb(main):046> foo.valid?
|
|
922
|
+
=> false
|
|
923
|
+
irb(main):047> foo.errors
|
|
924
|
+
=> {age: {error_message: "Must be an integerRRRRRRrrr!"}}
|
|
916
925
|
```
|
|
917
926
|
Model example
|
|
918
927
|
```ruby
|
|
919
928
|
class User < Rubee::SequelObject
|
|
920
929
|
attr_accessor :id, :email, :password, :created, :updated
|
|
921
930
|
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
validate_before_persist! # This will validate and raise error in case invalid before saving to DB
|
|
931
|
+
validate_before_persist! # This will validate and raise error in case invalid before saving to DB
|
|
932
|
+
validate do
|
|
933
|
+
attribute(:email).required
|
|
934
|
+
.condition(
|
|
935
|
+
->{ email.match?(/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i) }, error: 'Wrong email format'
|
|
936
|
+
)
|
|
937
|
+
end
|
|
930
938
|
end
|
|
931
939
|
```
|
|
932
940
|
```bash
|
|
933
|
-
irb(main):
|
|
934
|
-
=>
|
|
935
|
-
|
|
941
|
+
irb(main):074> user = User.new(email: "wrong", password: 123)
|
|
942
|
+
=>
|
|
943
|
+
#<User:0x000000010d2c3e78
|
|
944
|
+
...
|
|
945
|
+
irb(main):075> user.valid?
|
|
936
946
|
=> false
|
|
937
|
-
irb(main):
|
|
938
|
-
=> {email: {
|
|
939
|
-
irb(main):
|
|
940
|
-
|
|
941
|
-
irb(main):
|
|
947
|
+
irb(main):076> user.errors
|
|
948
|
+
=> {email: {error: "Wrong email format"}}
|
|
949
|
+
irb(main):077> user.save
|
|
950
|
+
=>{email: {error: "Wrong email format"}} (Rubee::Validatable::Error) ..
|
|
951
|
+
irb(main):078> user.email = "ok@ok.com"
|
|
942
952
|
=> "ok@ok.com"
|
|
943
|
-
irb(main):
|
|
953
|
+
irb(main):079> user.valid?
|
|
944
954
|
=> true
|
|
945
|
-
irb(main):
|
|
955
|
+
irb(main):080> user.save
|
|
946
956
|
=> true
|
|
947
|
-
|
|
957
|
+
irb(main):081> user
|
|
958
|
+
=>
|
|
959
|
+
#<User:0x000000010d2c3e78
|
|
960
|
+
@__validation_state=#<Rubee::Validatable::State:0x000000010cb28628 @errors={}, @valid=true>,
|
|
961
|
+
@created=2025-11-30 17:18:52.254197 -0500,
|
|
962
|
+
@email="ok@ok.com",
|
|
963
|
+
@id=2260,
|
|
964
|
+
@password=123,
|
|
965
|
+
@updated=2025-11-30 17:18:52.254206 -0500>
|
|
948
966
|
```
|
|
949
967
|
[Back to content](#content)
|
|
950
968
|
|