yema 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.
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