organ 0.0.1 → 0.0.2
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/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: []
|