vladimerb 0.0.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.
data/src/chain.rb ADDED
@@ -0,0 +1,13 @@
1
+ require_relative "namespace"
2
+
3
+ class Vladimerb::Chain
4
+ def initialize validation_1, validation_2
5
+ @validation_1 = validation_1
6
+ @validation_2 = validation_2
7
+ end
8
+
9
+ def validate record
10
+ error_1 = @validation_1.validate(record)
11
+ error_1.empty? ? @validation_2.validate(record) : error_1
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ require_relative "namespace"
2
+
3
+ class Vladimerb::GreaterThan
4
+ def initialize field_name, minimum
5
+ @field_name = field_name
6
+ @minimum = minimum
7
+ end
8
+
9
+ def validate record
10
+ record.send(@field_name) > @minimum ?
11
+ [] :
12
+ [@field_name.to_s + " must be over " + @minimum.to_s + "." ]
13
+ end
14
+ end
data/src/join.rb ADDED
@@ -0,0 +1,13 @@
1
+ require_relative "namespace"
2
+
3
+ class Vladimerb::Join
4
+ def initialize required_1, required_2
5
+ @validation_1 = required_1
6
+ @validation_2 = required_2
7
+ end
8
+
9
+ def validate record
10
+ @validation_1.validate(record) + @validation_2.validate(record)
11
+ end
12
+ end
13
+
data/src/lambda.rb ADDED
@@ -0,0 +1,11 @@
1
+ require_relative "namespace"
2
+
3
+ class Vladimerb::LambdaValidation
4
+ def initialize &block
5
+ @block = block
6
+ end
7
+
8
+ def validate record
9
+ @block.call(record)
10
+ end
11
+ end
data/src/namespace.rb ADDED
@@ -0,0 +1,2 @@
1
+ module Vladimerb
2
+ end
data/src/pattern.rb ADDED
@@ -0,0 +1,23 @@
1
+ require_relative "namespace"
2
+
3
+ class Vladimerb::Pattern
4
+ def initialize field_name, regex, options=nil
5
+ @field_name = field_name
6
+ @regex = regex
7
+ @custom_message = options[:message] unless options.nil?
8
+ end
9
+
10
+ def validate record
11
+ record.send(@field_name).match(@regex).nil? ?
12
+ [error_message] :
13
+ []
14
+ end
15
+
16
+ private
17
+
18
+ def error_message
19
+ @custom_message.nil? ?
20
+ @field_name.to_s + " is not formatted correctly." :
21
+ @custom_message
22
+ end
23
+ end
data/src/predicate.rb ADDED
@@ -0,0 +1,13 @@
1
+ require_relative "namespace"
2
+
3
+ class Vladimerb::Predicate
4
+ def initialize field_name, method, msg
5
+ @field_name = field_name
6
+ @method = method.to_proc
7
+ @msg = msg
8
+ end
9
+
10
+ def validate record
11
+ @method.call(record.send(@field_name)) ? [] : [@msg]
12
+ end
13
+ end
data/src/required.rb ADDED
@@ -0,0 +1,30 @@
1
+ require_relative "namespace"
2
+
3
+ class Vladimerb::Required
4
+ def initialize field_name, options=nil
5
+ @field_name = field_name
6
+ @custom_message = options[:message] unless options.nil?
7
+ end
8
+
9
+ def validate record
10
+ data = record.send(@field_name)
11
+ not_provided?(data) ? [error_message] : []
12
+ end
13
+
14
+ private
15
+ def error_message
16
+ @custom_message.nil? ?
17
+ @field_name.to_s + " is required." :
18
+ @custom_message
19
+ end
20
+
21
+ def not_provided? data
22
+ data.nil? or is_empty?(data)
23
+ end
24
+
25
+ def is_empty? data
26
+ data.empty? if data.respond_to?(:empty?)
27
+ end
28
+
29
+ end
30
+
data/src/vladimerb.rb ADDED
@@ -0,0 +1,42 @@
1
+ require_relative "join"
2
+ require_relative "chain"
3
+ require_relative "required"
4
+ require_relative "greater_than"
5
+ require_relative "lambda"
6
+ require_relative "pattern"
7
+ require_relative "predicate"
8
+
9
+ module Vladimerb
10
+ def join *validations
11
+ validations.reduce{ |tree, validation|
12
+ Join.new tree, validation }
13
+ end
14
+
15
+ def chain *validations
16
+ validations.reduce{ |tree, validation|
17
+ Chain.new tree, validation }
18
+ end
19
+
20
+ def required field_name
21
+ Required.new field_name
22
+ end
23
+
24
+ def greater_than field_name, minimum
25
+ GreaterThan.new field_name, minimum
26
+ end
27
+
28
+ def lambda_validation &block
29
+ LambdaValidation.new &block
30
+ end
31
+
32
+ def pattern field_name, regex
33
+ Pattern.new field_name, regex
34
+ end
35
+
36
+ def predicate field_name, method, msg
37
+ Predicate.new field_name, method, msg
38
+ end
39
+ end
40
+
41
+ include Vladimerb
42
+
data/test/chain.rb ADDED
@@ -0,0 +1,19 @@
1
+ require_relative "test_helper"
2
+
3
+ class ChainTest < Test::Unit::TestCase
4
+ def test_shows_first_error
5
+ assert_errors Candidate.new(nil, nil),
6
+ chain(required(:name),
7
+ required(:age)),
8
+ ["name is required."]
9
+ end
10
+
11
+ def test_shows_first_error_set_in_tree
12
+ assert_errors Candidate.new(nil, nil),
13
+ Chain.new(
14
+ join(required(:name),
15
+ required(:age)),
16
+ greater_than(:age, 18)),
17
+ ["name is required.", "age is required."]
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ require_relative "test_helper"
2
+
3
+
4
+ class GreaterThanTest < Test::Unit::TestCase
5
+ def tests_fails_when_number_not_greater
6
+ assert_errors Candidate.new("Jill", 12),
7
+ GreaterThan.new(:age, 18),
8
+ ["age must be over 18."]
9
+ end
10
+
11
+ def tests_passes_when_number_is_greater
12
+ assert_errors Candidate.new("Jill", 24),
13
+ GreaterThan.new(:age, 18),
14
+ []
15
+ end
16
+ end
17
+
data/test/helpers.rb ADDED
@@ -0,0 +1,61 @@
1
+ require_relative "test_helper.rb"
2
+
3
+ class HelpersTest < Test::Unit::TestCase
4
+ include Helpers
5
+
6
+ def test_join_can_compose_multiple_validations
7
+ assert_errors Candidate.new("Fred", 50),
8
+ join(required(:name),
9
+ required(:age),
10
+ greater_than(:age, 40)),
11
+ []
12
+ end
13
+
14
+ def test_chain_can_compose_multiple_validations
15
+ assert_errors Candidate.new(nil, nil),
16
+ chain(required(:name),
17
+ required(:age),
18
+ greater_than(:age, 40)),
19
+ ["name is required."]
20
+ end
21
+
22
+ def test_can_build_composite_validation_attractively
23
+ validation = join(required(:name),
24
+ chain(required(:age),
25
+ greater_than(:age, 40)))
26
+
27
+ assert_errors Candidate.new("Fred", 50), validation,
28
+ []
29
+
30
+ assert_errors Candidate.new("Fred", 30), validation,
31
+ ["age must be over 40."]
32
+
33
+ assert_errors Candidate.new("", 50), validation,
34
+ ["name is required."]
35
+
36
+ assert_errors Candidate.new(nil, nil), validation,
37
+ ["name is required.", "age is required."]
38
+ end
39
+
40
+ def test_lambda_validations_can_be_built_with_blocks
41
+ assert_errors Candidate.new("Colin Logan Campbell-McPherson", 24),
42
+ (lambda_validation do |candidate|
43
+ (candidate.name.to_s + candidate.age.to_s).length > 10 ?
44
+ ["Name and Age combined take up too much room to display"] : []
45
+ end),
46
+ ["Name and Age combined take up too much room to display"]
47
+ end
48
+
49
+ def test_pattern_validations_can_be_built_with_blocks
50
+ assert_errors Candidate.new("Logan Campbell-McPherson", 24),
51
+ pattern(:name, /^[a-zA-Z]+$/),
52
+ ["name is not formatted correctly."]
53
+ end
54
+
55
+ def test_predicate_can_be_built_with_blocks
56
+ assert_errors Candidate.new("Jill", 24),
57
+ predicate(:name, :nil?, "Name must be nil."),
58
+ ["Name must be nil."]
59
+ end
60
+ end
61
+
data/test/join.rb ADDED
@@ -0,0 +1,10 @@
1
+ require_relative "test_helper.rb"
2
+
3
+ class JoinTest < Test::Unit::TestCase
4
+ def test_shows_all_errors
5
+ assert_errors Candidate.new(nil, nil),
6
+ join(required(:name),
7
+ required(:age)),
8
+ ["name is required.", "age is required."]
9
+ end
10
+ end
data/test/lambda.rb ADDED
@@ -0,0 +1,12 @@
1
+ require_relative "test_helper.rb"
2
+
3
+ class LambdaTest < Test::Unit::TestCase
4
+ def tests_against_lambda_and_fails
5
+ assert_errors Candidate.new(nil, 24),
6
+ (lambda_validation do |record|
7
+ record.name.nil? ? ["Name is required."] : []
8
+ end),
9
+ ["Name is required."]
10
+ end
11
+ end
12
+
data/test/pattern.rb ADDED
@@ -0,0 +1,23 @@
1
+ require_relative "test_helper.rb"
2
+
3
+ class PatternTest < Test::Unit::TestCase
4
+ def tests_a_value_matches_a_regex
5
+ assert_errors Candidate.new("Fred", 50),
6
+ pattern(:name, /ed/),
7
+ []
8
+ end
9
+
10
+ def tests_a_value_does_not_match_a_regex
11
+ assert_errors Candidate.new("Fred", 24),
12
+ pattern(:name, /ill/),
13
+ ["name is not formatted correctly."]
14
+ end
15
+
16
+ def tests_a_value_does_not_match_a_regex_and_gives_custom_error_message
17
+ assert_errors Candidate.new("Fred", 24),
18
+ pattern(:name, /ill/, message: "Name is insufficiently ill"),
19
+ ["Name is insufficiently ill"]
20
+ end
21
+
22
+ end
23
+
data/test/predicate.rb ADDED
@@ -0,0 +1,17 @@
1
+ require File.dirname(File.expand_path(__FILE__)) + "/test_helper.rb"
2
+ require File.dirname(File.expand_path(__FILE__)) + "/../src/predicate.rb"
3
+
4
+
5
+ class PredicateTest < Test::Unit::TestCase
6
+ def tests_against_predicate_and_fails
7
+ assert_errors Candidate.new("Jill", 24),
8
+ Predicate.new(:name, :nil?, "Name must be nil."),
9
+ ["Name must be nil."]
10
+ end
11
+
12
+ def tests_against_predicate_and_succeeds
13
+ assert_errors Candidate.new(nil, 24),
14
+ Predicate.new(:name, :nil?, "Name must be nil."),
15
+ []
16
+ end
17
+ end
data/test/require.rb ADDED
@@ -0,0 +1,41 @@
1
+ require File.dirname(File.expand_path(__FILE__)) + "/test_helper.rb"
2
+ require File.dirname(File.expand_path(__FILE__)) + "/../src/required.rb"
3
+
4
+ class RequiredTest < Test::Unit::TestCase
5
+ def test_succeeds_for_candidate_with_name
6
+ assert_errors Candidate.new("Fred", 50),
7
+ Required.new(:name),
8
+ []
9
+ end
10
+
11
+ def test_fails_for_candidate_without_name
12
+ assert_errors Candidate.new(nil, 24),
13
+ Required.new(:name),
14
+ ["name is required."]
15
+ end
16
+
17
+ def test_fails_for_candidate_with_blank_name
18
+ assert_errors Candidate.new("", 24),
19
+ Required.new(:name),
20
+ ["name is required."]
21
+ end
22
+
23
+ def test_fails_for_candidate_without_age
24
+ assert_errors Candidate.new("Bob", nil),
25
+ Required.new(:age),
26
+ ["age is required."]
27
+ end
28
+
29
+ def test_fails_for_required_data_that_do_not_have_empty_method
30
+ assert_errors Candidate.new("Bob", 20),
31
+ Required.new(:age),
32
+ []
33
+ end
34
+
35
+ def test_fails_with_custom_error_message
36
+ assert_errors Candidate.new(nil, 24),
37
+ Required.new(:name, message: "You gotta have a name!"),
38
+ ["You gotta have a name!"]
39
+ end
40
+ end
41
+
@@ -0,0 +1,19 @@
1
+ require "rubygems"
2
+ gem "test-unit", "2.5.0"
3
+ require "test/unit"
4
+ require_relative "../src/vladimerb"
5
+
6
+ class Candidate
7
+ attr_accessor :name, :age
8
+
9
+ def initialize(name, age)
10
+ @name = name
11
+ @age = age
12
+ end
13
+ end
14
+
15
+ def assert_errors(data, validation, expected_errors)
16
+ actual_errors = validation.validate(data)
17
+ assert_equal(expected_errors, actual_errors)
18
+ end
19
+
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vladimerb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Logan Campbell
9
+ - Pei Shi Yong
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-06-20 00:00:00.000000000Z
14
+ dependencies: []
15
+ description: Composable data validators
16
+ email: colin@logaan.net
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - src/chain.rb
22
+ - src/greater_than.rb
23
+ - src/join.rb
24
+ - src/lambda.rb
25
+ - src/namespace.rb
26
+ - src/pattern.rb
27
+ - src/predicate.rb
28
+ - src/required.rb
29
+ - src/vladimerb.rb
30
+ - test/chain.rb
31
+ - test/greater_than.rb
32
+ - test/helpers.rb
33
+ - test/join.rb
34
+ - test/lambda.rb
35
+ - test/pattern.rb
36
+ - test/predicate.rb
37
+ - test/require.rb
38
+ - test/test_helper.rb
39
+ homepage: https://github.com/logaan/vladimerb
40
+ licenses: []
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - src
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 1.8.10
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Composable data validators
63
+ test_files:
64
+ - test/chain.rb
65
+ - test/greater_than.rb
66
+ - test/helpers.rb
67
+ - test/join.rb
68
+ - test/lambda.rb
69
+ - test/pattern.rb
70
+ - test/predicate.rb
71
+ - test/require.rb
72
+ - test/test_helper.rb