organ 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/organ.rb +1 -1
- data/lib/organ/coercer.rb +3 -1
- data/organ.gemspec +3 -3
- data/spec/coercer_spec.rb +114 -0
- data/spec/form_spec.rb +122 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/validations_spec.rb +161 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd33328998e87df6ab61e1dc2bd376300c697117
|
4
|
+
data.tar.gz: f5f0a2ae5eb51e58f51272916e3d6fb40e9dbbca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d44b2013528d2fb53af496ab000cbb14cc3d418c30b66a39a9dfb944bcf65c12cb1632b5e5fd8e1fce56d6666b44ff400fe162f9709ccea5424c9f71f6d698a
|
7
|
+
data.tar.gz: c4ae75c498f063defb2cd5baa94a112f23e4f64c04dcaa374f6b65ac25e2730dec0e6c9b6184ac7a1caf15abe240902d534314c952472fe84bcaf7cf0e574000
|
data/lib/organ.rb
CHANGED
data/lib/organ/coercer.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "date"
|
2
|
+
|
1
3
|
module Organ
|
2
4
|
module Coercer
|
3
5
|
|
@@ -124,7 +126,7 @@ module Organ
|
|
124
126
|
#
|
125
127
|
# @api semipublic
|
126
128
|
def coerce_date(value, options = {})
|
127
|
-
value =
|
129
|
+
value = coerce_string(value)
|
128
130
|
begin
|
129
131
|
Date.strptime(value, "%Y-%m-%d")
|
130
132
|
rescue ArgumentError
|
data/organ.gemspec
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "organ"
|
3
|
-
s.version = "0.0.
|
3
|
+
s.version = "0.0.2"
|
4
4
|
s.summary = "Forms with integrated validations and attribute coercing."
|
5
5
|
s.description = "A small library for manipulating form-based data with validations and attributes coercion."
|
6
6
|
s.authors = ["Sebastian Borrazas"]
|
7
7
|
s.email = ["seba.borrazas@gmail.com"]
|
8
8
|
s.homepage = "http://github.com/sborrazas/organ"
|
9
|
+
s.license = "MIT"
|
9
10
|
|
10
11
|
s.files = Dir[
|
11
12
|
"LICENSE",
|
12
|
-
"CHANGELOG",
|
13
13
|
"README.md",
|
14
14
|
"Rakefile",
|
15
15
|
"lib/**/*.rb",
|
16
16
|
"*.gemspec",
|
17
|
-
"
|
17
|
+
"spec/*.*"
|
18
18
|
]
|
19
19
|
|
20
20
|
s.require_paths = ["lib"]
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require_relative "spec_helper"
|
2
|
+
|
3
|
+
describe Organ::Coercer do
|
4
|
+
let(:coercer) do
|
5
|
+
Module.new do
|
6
|
+
extend Organ::Coercer
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#coerce_string" do
|
11
|
+
describe "when value is truthy" do
|
12
|
+
it "returns a string" do
|
13
|
+
assert_equal("truthy!", coercer.coerce_string("truthy!"))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "when value is falsy" do
|
18
|
+
it "returns nil" do
|
19
|
+
assert_nil(coercer.coerce_string(false))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "when sending a :trim option to true" do
|
24
|
+
it "returns a string with no trailing spaces" do
|
25
|
+
result = coercer.coerce_string(" \n truthy ! \n ", :trim => true)
|
26
|
+
assert_equal("truthy !", result)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#coerce_boolean" do
|
32
|
+
describe "when value is truthy" do
|
33
|
+
it "returns true" do
|
34
|
+
assert_equal(true, coercer.coerce_boolean("truthy"))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "when value is falsy" do
|
39
|
+
it "returns false" do
|
40
|
+
assert_equal(false, coercer.coerce_boolean(nil))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#coerce_array" do
|
46
|
+
describe "when value is an array" do
|
47
|
+
describe "when no :element_type option is given" do
|
48
|
+
it "returns the array" do
|
49
|
+
value = ["1", "2", "3"]
|
50
|
+
assert_equal(value, coercer.coerce_array(value))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "when :element_type option is given" do
|
55
|
+
it "coerces the elements inside" do
|
56
|
+
value = ["1", "2", "3"]
|
57
|
+
result = coercer.coerce_array(value, :element_type => :integer)
|
58
|
+
assert_equal([1, 2, 3], result)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "when value is a hash" do
|
64
|
+
it "returns its values" do
|
65
|
+
value = { "1" => 2, "2" => 4 }
|
66
|
+
result = coercer.coerce_array(value)
|
67
|
+
assert_includes(result, 2)
|
68
|
+
assert_includes(result, 4)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "when value is not an array or a hash" do
|
73
|
+
it "returns an empty array" do
|
74
|
+
assert_equal([], coercer.coerce_array(nil))
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "#coerce_float" do
|
80
|
+
describe "when value doesn't have a float format" do
|
81
|
+
it "returns nil" do
|
82
|
+
assert_nil(coercer.coerce_float("nope"))
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "when has a float format" do
|
87
|
+
it "returns a float" do
|
88
|
+
values = {
|
89
|
+
".99" => 0.99,
|
90
|
+
"12.3456" => 12.3456,
|
91
|
+
"5" => 5.0
|
92
|
+
}
|
93
|
+
values.each do |value, expected|
|
94
|
+
assert_equal(expected, coercer.coerce_float(value))
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "#coerce_date" do
|
101
|
+
describe "when value doesn't have a date format" do
|
102
|
+
it "returns nil" do
|
103
|
+
assert_nil(coercer.coerce_date("not a date"))
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "when value has a date format" do
|
108
|
+
it "returns a date" do
|
109
|
+
assert_equal(Date.civil(2014, 9, 28), coercer.coerce_date("2014-09-28"))
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
data/spec/form_spec.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
require_relative "spec_helper"
|
2
|
+
|
3
|
+
describe Organ::Form do
|
4
|
+
|
5
|
+
describe ".attribute" do
|
6
|
+
it "defines an attribute reader" do
|
7
|
+
form_klass = Class.new(Organ::Form) do
|
8
|
+
attribute(:username)
|
9
|
+
end
|
10
|
+
form = form_klass.new(:username => "user")
|
11
|
+
|
12
|
+
assert_equal("user", form.username)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "if :skip_reader option is true" do
|
16
|
+
it "doesn't define an attribute reader" do
|
17
|
+
form_klass = Class.new(Organ::Form) do
|
18
|
+
attribute(:username, :skip_reader => true)
|
19
|
+
end
|
20
|
+
form = form_klass.new(:username => "user")
|
21
|
+
|
22
|
+
refute(form.respond_to?(:username))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "if type is given" do
|
27
|
+
it "coerces the value" do
|
28
|
+
form_klass = Class.new(Organ::Form) do
|
29
|
+
attribute(:username, :type => :fruit)
|
30
|
+
|
31
|
+
def coerce_fruit(value, options = {})
|
32
|
+
"apple"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
form = form_klass.new(:username => "user")
|
36
|
+
|
37
|
+
assert_equal("apple", form.username)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#set_attributes" do
|
43
|
+
form_klass = Class.new(Organ::Form) do
|
44
|
+
attribute(:username)
|
45
|
+
attribute(:password)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "sets all attributes given" do
|
49
|
+
form = form_klass.new
|
50
|
+
form.set_attributes(:username => "user")
|
51
|
+
|
52
|
+
assert_equal("user", form.username)
|
53
|
+
assert_nil(form.password)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "#attributes" do
|
58
|
+
form_klass = Class.new(Organ::Form) do
|
59
|
+
attribute(:username)
|
60
|
+
attribute(:password)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "retrieves all form attributes" do
|
64
|
+
form = form_klass.new(:username => "user")
|
65
|
+
attributes = form.attributes
|
66
|
+
|
67
|
+
assert_equal(2, attributes.size)
|
68
|
+
assert_includes(attributes, :username)
|
69
|
+
assert_includes(attributes, :password)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#perform!" do
|
75
|
+
let(:form_klass) do
|
76
|
+
Class.new(Organ::Form) do
|
77
|
+
attribute(:username)
|
78
|
+
attribute(:password)
|
79
|
+
|
80
|
+
def validate
|
81
|
+
end
|
82
|
+
|
83
|
+
def perform
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
let(:form) { form_klass.new }
|
89
|
+
|
90
|
+
describe "if no errors during validate or perform" do
|
91
|
+
it "doesn't raise any exceptions" do
|
92
|
+
form.perform!
|
93
|
+
assert(true)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "if any errors on validate" do
|
98
|
+
it "raises an error" do
|
99
|
+
def form.validate
|
100
|
+
append_error(:username, :invalid)
|
101
|
+
end
|
102
|
+
|
103
|
+
assert_raises(Organ::ValidationError) do
|
104
|
+
form.perform!
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "if any errors on perform" do
|
110
|
+
it "raises an error" do
|
111
|
+
def form.perform
|
112
|
+
append_error(:username, :invalid)
|
113
|
+
end
|
114
|
+
|
115
|
+
assert_raises(Organ::ValidationError) do
|
116
|
+
form.perform!
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
require_relative "spec_helper"
|
2
|
+
|
3
|
+
describe Organ::Validations do
|
4
|
+
let(:new_errors) { [] }
|
5
|
+
let(:username_value) { nil }
|
6
|
+
let(:validator) do
|
7
|
+
Module.new do
|
8
|
+
extend Organ::Validations
|
9
|
+
|
10
|
+
def self.validate
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
before do
|
16
|
+
value = username_value
|
17
|
+
validator.define_singleton_method(:username) { value }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#errors" do
|
21
|
+
it "returns an empty hash" do
|
22
|
+
errors = validator.errors
|
23
|
+
assert(errors.empty?)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#valid?" do
|
28
|
+
describe "when no errors added on #validate" do
|
29
|
+
it "is valid" do
|
30
|
+
assert(validator.valid?)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "when errors added on #validate" do
|
35
|
+
it "is not valid" do
|
36
|
+
def validator.validate
|
37
|
+
append_error(:username, :invalid)
|
38
|
+
end
|
39
|
+
refute(validator.valid?)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#append_error" do
|
45
|
+
it "appends an error to the attribute" do
|
46
|
+
validator.append_error(:username, :invalid)
|
47
|
+
assert_equal(1, validator.errors[:username].size)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#validate_presence" do
|
52
|
+
describe "when attribute has nil value" do
|
53
|
+
it "appends an error" do
|
54
|
+
validator.validate_presence(:username)
|
55
|
+
assert_includes(validator.errors[:username], :blank)
|
56
|
+
assert_equal(1, validator.errors[:username].size)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "when attribute has empty string value" do
|
61
|
+
let(:username_value) { "" }
|
62
|
+
|
63
|
+
it "appends an error" do
|
64
|
+
validator.validate_presence(:username)
|
65
|
+
assert_includes(validator.errors[:username], :blank)
|
66
|
+
assert_equal(1, validator.errors[:username].size)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#validate_uniqueness" do
|
72
|
+
describe "when block returns false" do
|
73
|
+
it "appends a :taken error" do
|
74
|
+
validator.validate_uniqueness(:username) { |u| false }
|
75
|
+
assert_includes(validator.errors[:username], :taken)
|
76
|
+
assert_equal(1, validator.errors[:username].size)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "#validate_email_format" do
|
82
|
+
describe "when value is not an email" do
|
83
|
+
let(:username_value) { "not.an@email" }
|
84
|
+
|
85
|
+
it "appends an :invalid error" do
|
86
|
+
validator.validate_email_format(:username)
|
87
|
+
assert_includes(validator.errors[:username], :invalid)
|
88
|
+
assert_equal(1, validator.errors[:username].size)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "#validate_format" do
|
94
|
+
describe "when value does not match the regexp" do
|
95
|
+
let(:username_value) { "ema8l" }
|
96
|
+
|
97
|
+
it "appends an :invalid error" do
|
98
|
+
validator.validate_format(:username, /\A[a-z]+\Z/)
|
99
|
+
assert_includes(validator.errors[:username], :invalid)
|
100
|
+
assert_equal(1, validator.errors[:username].size)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "#validate_length" do
|
106
|
+
describe "when value size is less than the min" do
|
107
|
+
let(:username_value) { "ema8l" }
|
108
|
+
|
109
|
+
it "appends a :too_short error" do
|
110
|
+
validator.validate_length(:username, :min => 8)
|
111
|
+
assert_includes(validator.errors[:username], :too_short)
|
112
|
+
assert_equal(1, validator.errors[:username].size)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "when value size is greater than the max" do
|
117
|
+
let(:username_value) { "ema8l" }
|
118
|
+
|
119
|
+
it "appends a :too_long error" do
|
120
|
+
validator.validate_length(:username, :max => 2)
|
121
|
+
assert_includes(validator.errors[:username], :too_long)
|
122
|
+
assert_equal(1, validator.errors[:username].size)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "#validate_inclusion" do
|
128
|
+
describe "when is not included in the list" do
|
129
|
+
let(:username_value) { 1 }
|
130
|
+
|
131
|
+
it "appends a :not_included error" do
|
132
|
+
validator.validate_inclusion(:username, [2, 3])
|
133
|
+
assert_includes(validator.errors[:username], :not_included)
|
134
|
+
assert_equal(1, validator.errors[:username].size)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe "#validate_range" do
|
140
|
+
describe "when value is less than the min" do
|
141
|
+
let(:username_value) { 5 }
|
142
|
+
|
143
|
+
it "appends a :less_than error" do
|
144
|
+
validator.validate_range(:username, :min => 8)
|
145
|
+
assert_includes(validator.errors[:username], :less_than)
|
146
|
+
assert_equal(1, validator.errors[:username].size)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "when value is greater than the max" do
|
151
|
+
let(:username_value) { 5 }
|
152
|
+
|
153
|
+
it "appends a :greater_than error" do
|
154
|
+
validator.validate_range(:username, :max => 3)
|
155
|
+
assert_includes(validator.errors[:username], :greater_than)
|
156
|
+
assert_equal(1, validator.errors[:username].size)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: organ
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastian Borrazas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-28 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A small library for manipulating form-based data with validations and
|
14
14
|
attributes coercion.
|
@@ -27,8 +27,13 @@ files:
|
|
27
27
|
- lib/organ/validation_error.rb
|
28
28
|
- lib/organ/validations.rb
|
29
29
|
- organ.gemspec
|
30
|
+
- spec/coercer_spec.rb
|
31
|
+
- spec/form_spec.rb
|
32
|
+
- spec/spec_helper.rb
|
33
|
+
- spec/validations_spec.rb
|
30
34
|
homepage: http://github.com/sborrazas/organ
|
31
|
-
licenses:
|
35
|
+
licenses:
|
36
|
+
- MIT
|
32
37
|
metadata: {}
|
33
38
|
post_install_message:
|
34
39
|
rdoc_options: []
|