yema 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/.gitignore +18 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +70 -0
  7. data/Rakefile +1 -0
  8. data/lib/yema.rb +33 -0
  9. data/lib/yema/error.rb +11 -0
  10. data/lib/yema/exceptions.rb +3 -0
  11. data/lib/yema/registry/rule.rb +26 -0
  12. data/lib/yema/rule.rb +32 -0
  13. data/lib/yema/rule/format.rb +29 -0
  14. data/lib/yema/rule/inclusion.rb +29 -0
  15. data/lib/yema/rule/length.rb +34 -0
  16. data/lib/yema/rule/required.rb +17 -0
  17. data/lib/yema/rule/strong_type.rb +58 -0
  18. data/lib/yema/validations.rb +30 -0
  19. data/lib/yema/validator.rb +25 -0
  20. data/lib/yema/version.rb +3 -0
  21. data/lib/yema/virtus/attribute.rb +48 -0
  22. data/lib/yema/virtus/attribute/array.rb +12 -0
  23. data/lib/yema/virtus/attribute/numeric.rb +12 -0
  24. data/lib/yema/virtus/attribute/string.rb +16 -0
  25. data/lib/yema/virtus/builder.rb +17 -0
  26. data/lib/yema/virtus/builder/format.rb +13 -0
  27. data/lib/yema/virtus/builder/inclusion.rb +13 -0
  28. data/lib/yema/virtus/builder/length.rb +13 -0
  29. data/lib/yema/virtus/builder/required.rb +13 -0
  30. data/lib/yema/virtus/builder/strong_type.rb +18 -0
  31. data/lib/yema/virtus/validations.rb +28 -0
  32. data/spec/integration/rule/format_spec.rb +23 -0
  33. data/spec/integration/rule/inclusion_spec.rb +28 -0
  34. data/spec/integration/rule/length_spec.rb +40 -0
  35. data/spec/integration/rule/required_spec.rb +22 -0
  36. data/spec/integration/rule/strong_type_spec.rb +27 -0
  37. data/spec/integration/virtus/combination_spec.rb +58 -0
  38. data/spec/integration/virtus/format_spec.rb +22 -0
  39. data/spec/integration/virtus/inclusion_spec.rb +26 -0
  40. data/spec/integration/virtus/length_spec.rb +36 -0
  41. data/spec/integration/virtus/required_spec.rb +21 -0
  42. data/spec/integration/virtus/strong_type_spec.rb +40 -0
  43. data/spec/shared/invalid_options.rb +6 -0
  44. data/spec/shared/invalid_resource.rb +6 -0
  45. data/spec/shared/valid_options.rb +6 -0
  46. data/spec/shared/valid_resource.rb +6 -0
  47. data/spec/spec_helper.rb +9 -0
  48. data/spec/unit/rule/format/valid_options_spec.rb +13 -0
  49. data/spec/unit/rule/inclusion/valid_options_spec.rb +15 -0
  50. data/spec/unit/rule/length/valid_options_spec.rb +16 -0
  51. data/spec/unit/rule/required_options_spec.rb +18 -0
  52. data/spec/unit/rule/strong_type/valid_options_spec.rb +13 -0
  53. data/spec/unit/validations/rules_spec.rb +15 -0
  54. data/spec/unit/validations/valid_spec.rb +41 -0
  55. data/spec/unit/validator/errors_spec.rb +26 -0
  56. data/spec/unit/validator/valid_predicate_spec.rb +31 -0
  57. data/spec/unit/virtus/not_supported_type_spec.rb +11 -0
  58. data/yema.gemspec +26 -0
  59. metadata +210 -0
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Yema::Virtus::Rule::Format' do
4
+
5
+ subject { described_class.new(name: value).errors }
6
+
7
+ let(:described_class) do
8
+ Class.new do
9
+ include Yema::Virtus::Validations
10
+ attribute :name, String, strict: :none, format: /abc/
11
+ self
12
+ end
13
+ end
14
+
15
+ it_behaves_like "valid resource", "abc"
16
+ it_behaves_like "valid resource", "1abcs"
17
+
18
+ it_behaves_like "invalid resource", ""
19
+ it_behaves_like "invalid resource", nil
20
+ it_behaves_like "invalid resource", false
21
+ it_behaves_like "invalid resource", 1
22
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Yema::Virtus::Rule::Inclusion' do
4
+
5
+ subject { described_class.new(age: value).errors }
6
+
7
+ let(:described_class) do
8
+ Class.new do
9
+ include Yema::Virtus::Validations
10
+ attribute :age, Integer, strict: :none, within: 1..5
11
+ self
12
+ end
13
+ end
14
+
15
+ it_behaves_like "valid resource", 1
16
+ it_behaves_like "valid resource", 3
17
+ it_behaves_like "valid resource", 5
18
+
19
+ it_behaves_like "invalid resource", 0
20
+ it_behaves_like "invalid resource", 6
21
+ it_behaves_like "invalid resource", "3a"
22
+ it_behaves_like "invalid resource", "abc"
23
+ it_behaves_like "invalid resource", false
24
+ it_behaves_like "invalid resource", nil
25
+ it_behaves_like "invalid resource", ""
26
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Yema::Virtus::Rule::Length' do
4
+
5
+ subject { described_class.new(name: value).errors }
6
+
7
+ context "fixed length" do
8
+ let(:described_class) do
9
+ Class.new do
10
+ include Yema::Virtus::Validations
11
+ attribute :name, String, strict: :none, length: 5
12
+ self
13
+ end
14
+ end
15
+
16
+ it_behaves_like "valid resource", "abcde"
17
+ it_behaves_like "valid resource", 12345
18
+ it_behaves_like "invalid resource", "a"
19
+ it_behaves_like "invalid resource", 5
20
+ end
21
+
22
+ context "range length" do
23
+ let(:described_class) do
24
+ Class.new do
25
+ include Yema::Virtus::Validations
26
+ attribute :name, String, strict: :none, length: 2..5
27
+ self
28
+ end
29
+ end
30
+
31
+ it_behaves_like "valid resource", "abcde"
32
+ it_behaves_like "valid resource", "abc"
33
+ it_behaves_like "valid resource", 5343
34
+ it_behaves_like "invalid resource", "a"
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Yema::Virtus::Rule::Required' do
4
+
5
+ subject { described_class.new(name: value).errors }
6
+
7
+ let(:described_class) do
8
+ Class.new do
9
+ include Yema::Virtus::Validations
10
+ attribute :name, String, strict: :none, required: true
11
+ self
12
+ end
13
+ end
14
+
15
+ it_behaves_like "valid resource", "name"
16
+ it_behaves_like "valid resource", 5343
17
+ it_behaves_like "valid resource", false
18
+
19
+ it_behaves_like "invalid resource", ""
20
+ it_behaves_like "invalid resource", nil
21
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Yema::Virtus::Rule::StrongType' do
4
+
5
+ subject { described_class.new(age: value).errors }
6
+
7
+ context "default strict mode" do
8
+ let(:described_class) do
9
+ Class.new do
10
+ include Yema::Virtus::Validations
11
+ attribute :age, Integer
12
+ self
13
+ end
14
+ end
15
+
16
+ it_behaves_like "valid resource", 5343
17
+ it_behaves_like "valid resource", "4"
18
+ it_behaves_like "invalid resource", false
19
+ it_behaves_like "invalid resource", "name"
20
+ it_behaves_like "invalid resource", ""
21
+ it_behaves_like "invalid resource", nil
22
+ end
23
+
24
+ context "allow_nil strict mode" do
25
+ let(:described_class) do
26
+ Class.new do
27
+ include Yema::Virtus::Validations
28
+ attribute :age, Integer, strict: :allow_nil
29
+ self
30
+ end
31
+ end
32
+
33
+ it_behaves_like "valid resource", nil
34
+ it_behaves_like "valid resource", 123
35
+ it_behaves_like "valid resource", "2"
36
+ it_behaves_like "invalid resource", ""
37
+ it_behaves_like "invalid resource", true
38
+ it_behaves_like "invalid resource", "string"
39
+ end
40
+ end
@@ -0,0 +1,6 @@
1
+ shared_examples_for "invalid options" do |options|
2
+ context "with options: #{options.inspect}" do
3
+ let(:options) { options }
4
+ specify { expect{subject}.to raise_error(Yema::InvalidOptionError) }
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ shared_examples_for "invalid resource" do |value|
2
+ context "with value: #{value.inspect}" do
3
+ let(:value) { value }
4
+ specify { subject.count.should eql(1) }
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ shared_examples_for "valid options" do |options|
2
+ context "with options: #{options.inspect}" do
3
+ let(:options) { options }
4
+ specify { expect{subject}.to_not raise_error }
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ shared_examples_for "valid resource" do |value|
2
+ context "with value: #{value.inspect}" do
3
+ let(:value) { value }
4
+ it { should be_empty }
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ if ENV['COV']
2
+ require 'simplecov'
3
+ SimpleCov.start do
4
+ add_filter "/spec/"
5
+ end
6
+ end
7
+
8
+ require 'yema'
9
+ Dir[File.expand_path('../shared/**/*.rb', __FILE__)].each { |file| require file }
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yema::Rule::Format, 'valid options' do
4
+
5
+ subject { described_class.new(:foo, options) }
6
+
7
+ it_behaves_like "valid options", {format: /abc/}
8
+
9
+ it_behaves_like "invalid options", {}
10
+ it_behaves_like "invalid options", {format: '3'}
11
+ it_behaves_like "invalid options", {format: [3, 4]}
12
+ it_behaves_like "invalid options", {format: 3}
13
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yema::Rule::Inclusion, 'valid options' do
4
+
5
+ subject { described_class.new(:foo, options) }
6
+
7
+ it_behaves_like "valid options", {within: [3, 4]}
8
+ it_behaves_like "valid options", {within: 3..4}
9
+
10
+ it_behaves_like "invalid options", {}
11
+ it_behaves_like "invalid options", {within: '3'}
12
+ it_behaves_like "invalid options", {within: 3.2}
13
+ it_behaves_like "invalid options", {within: false}
14
+ it_behaves_like "invalid options", {within: 3}
15
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yema::Rule::Length, 'valid options' do
4
+
5
+ subject { described_class.new(:foo, options) }
6
+
7
+ it_behaves_like "valid options", {length: 3}
8
+ it_behaves_like "valid options", {length: 3..4}
9
+
10
+ it_behaves_like "invalid options", {}
11
+ it_behaves_like "invalid options", {length: '3'}
12
+ it_behaves_like "invalid options", {length: [3, 4]}
13
+ it_behaves_like "invalid options", {length: 3.2}
14
+ it_behaves_like "invalid options", {length: false}
15
+ it_behaves_like "invalid options", {height: 3}
16
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yema::Rule, '.required_options' do
4
+
5
+ subject { described_class.new(:foo, options) }
6
+
7
+ let(:described_class) do
8
+ Class.new(Yema::Rule) do
9
+ def self.required_options
10
+ [:length]
11
+ end
12
+ end
13
+ end
14
+
15
+ it_behaves_like "invalid options", {}
16
+ it_behaves_like "invalid options", {size:24}
17
+ it_behaves_like "valid options", {length: 123, size:24}
18
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yema::Rule::StrongType, 'valid options' do
4
+
5
+ subject { described_class.new(:foo, options) }
6
+
7
+ it_behaves_like "valid options", {type: String}
8
+ it_behaves_like "valid options", {type: String, strict: :high}
9
+ it_behaves_like "valid options", {type: String, strict: :allow_nil}
10
+ it_behaves_like "invalid options", {}
11
+ it_behaves_like "invalid options", {strict: :else}
12
+ it_behaves_like "invalid options", {type: String, strict: :else}
13
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yema::Validations, "#rules" do
4
+
5
+ subject { described_class.rules }
6
+
7
+ let(:described_class) do
8
+ Class.new do
9
+ include Yema::Validations
10
+ end
11
+ end
12
+
13
+ it { should be_instance_of(Yema::Registry::Rule) }
14
+
15
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yema::Validations, "#valid?" do
4
+
5
+ subject { model.valid? }
6
+
7
+ let(:described_class) do
8
+ Class.new do
9
+ include Yema::Validations
10
+ end
11
+ end
12
+ let(:model) { described_class.new }
13
+ let(:rule) { stub('rule', errors: Set.new(errors)) }
14
+
15
+ before do
16
+ described_class.rules.add(rule)
17
+ end
18
+
19
+ context "when valid" do
20
+ let(:errors) { [] }
21
+
22
+ it { should be_true }
23
+ specify { model.errors.should be_empty }
24
+
25
+ context "add 1 invalid rule" do
26
+ let(:invalid_rule) { stub('invalid', errors: Set.new([stub('error')])) }
27
+ before { described_class.rules.add(invalid_rule) }
28
+
29
+ it { should be_false }
30
+ specify { model.rules.count.should eql(2) }
31
+ specify { model.errors.count.should eql(1) }
32
+ end
33
+ end
34
+
35
+ context "when invalid" do
36
+ let(:errors) { [stub('error1'), stub('error2')] }
37
+ it { should be_false }
38
+ specify { model.errors.count.should eql(2) }
39
+ end
40
+
41
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yema::Validator, "#errors" do
4
+
5
+ subject { validator.errors }
6
+
7
+ let(:validator) { described_class.new(rule, resource) }
8
+ let(:rule) { stub('rule') }
9
+ let(:resource) { stub('resource') }
10
+
11
+ before do
12
+ validator.should_receive(:valid?).and_return(valid)
13
+ end
14
+
15
+ context "when the attribute is valid" do
16
+ let(:valid) { true }
17
+ it_should_behave_like "valid resource"
18
+ end
19
+
20
+ context "when the attribute is invalid" do
21
+ let(:valid) { false }
22
+ it_should_behave_like "invalid resource"
23
+ specify { subject.first.should be_kind_of(Yema::Error) }
24
+ end
25
+
26
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yema::Validator, "#valid?" do
4
+
5
+ subject { validator.valid? }
6
+
7
+ let(:validator) { described_class.new(rule, resource) }
8
+ let(:rule) { mock('required_rule', attribute_name: :foo) }
9
+ let(:resource) { mock('resource', foo: value) }
10
+
11
+ before do
12
+ resource.should_receive(:foo).and_return(value)
13
+ end
14
+
15
+ context "when the value is valid" do
16
+ let(:value) { 'bar' }
17
+ before do
18
+ rule.should_receive(:matches?).with(value).and_return(true)
19
+ end
20
+ it { should be_true }
21
+ end
22
+
23
+ context "when the value is invalid" do
24
+ let(:value) { nil }
25
+ before do
26
+ rule.should_receive(:matches?).with(value).and_return(false)
27
+ end
28
+ it { should be_false }
29
+ end
30
+
31
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yema::Virtus::Attribute, '.build' do
4
+
5
+ subject { described_class.build(value) }
6
+ let(:value) { mock('not supported')}
7
+
8
+ specify "raise type error" do
9
+ expect{subject}.to raise_error(TypeError, "#{value.class} is not supported")
10
+ end
11
+ end
data/yema.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'yema/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "yema"
8
+ gem.version = Yema::VERSION
9
+ gem.authors = ["Handi Wiguna"]
10
+ gem.email = ["handi_wiguna@yahoo.com"]
11
+ gem.description = "Simple validation library with virtus integration"
12
+ gem.summary = gem.description
13
+ gem.homepage = "https://github.com/handiwiguna/yema"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_development_dependency "rspec"
21
+ gem.add_development_dependency "rake"
22
+ gem.add_development_dependency "simplecov"
23
+
24
+ gem.add_runtime_dependency "virtus", "0.5.4"
25
+ gem.add_runtime_dependency "equalizer", "0.0.2"
26
+ end