knight 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/.gitignore +1 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +9 -0
  4. data/Gemfile +7 -0
  5. data/Gemfile.dev +16 -0
  6. data/README.md +3 -1
  7. data/Rakefile +6 -1
  8. data/knight.gemspec +4 -1
  9. data/lib/knight.rb +18 -2
  10. data/lib/knight/error.rb +60 -0
  11. data/lib/knight/instance_methods.rb +69 -0
  12. data/lib/knight/result.rb +86 -0
  13. data/lib/knight/rule.rb +74 -0
  14. data/lib/knight/rule/exact_length.rb +63 -0
  15. data/lib/knight/rule/format.rb +62 -0
  16. data/lib/knight/rule/inclusion.rb +62 -0
  17. data/lib/knight/rule/maximum_length.rb +63 -0
  18. data/lib/knight/rule/minimum_length.rb +63 -0
  19. data/lib/knight/rule/presence.rb +37 -0
  20. data/lib/knight/rule/range_length.rb +64 -0
  21. data/lib/knight/validator.rb +91 -0
  22. data/lib/knight/version.rb +3 -1
  23. data/metrics/flog.yml +2 -0
  24. data/metrics/rubocop.yml +17 -0
  25. data/spec/integration/contextual_validator_spec.rb +41 -0
  26. data/spec/integration/knight_spec.rb +30 -0
  27. data/spec/spec_helper.rb +18 -0
  28. data/spec/unit/knight/error/class_methods/new_spec.rb +15 -0
  29. data/spec/unit/knight/error/message_spec.rb +26 -0
  30. data/spec/unit/knight/instance_methods/class_methods/included_spec.rb +24 -0
  31. data/spec/unit/knight/instance_methods/class_methods/new_spec.rb +12 -0
  32. data/spec/unit/knight/instance_methods/class_methods/validator_spec.rb +13 -0
  33. data/spec/unit/knight/instance_methods/run_spec.rb +29 -0
  34. data/spec/unit/knight/result/class_methods/new_spec.rb +13 -0
  35. data/spec/unit/knight/result/errors_spec.rb +71 -0
  36. data/spec/unit/knight/result/valid_predicate_spec.rb +28 -0
  37. data/spec/unit/knight/rule/class_methods/new_spec.rb +38 -0
  38. data/spec/unit/knight/rule/error_spec.rb +29 -0
  39. data/spec/unit/knight/rule/exact_length/class_methods/new_spec.rb +27 -0
  40. data/spec/unit/knight/rule/exact_length/matches_predicate_spec.rb +19 -0
  41. data/spec/unit/knight/rule/exact_length/to_hash_spec.rb +12 -0
  42. data/spec/unit/knight/rule/format/class_methods/new_spec.rb +26 -0
  43. data/spec/unit/knight/rule/format/matches_predicate_spec.rb +31 -0
  44. data/spec/unit/knight/rule/format/to_hash_spec.rb +12 -0
  45. data/spec/unit/knight/rule/inclusion/class_methods/new_spec.rb +28 -0
  46. data/spec/unit/knight/rule/inclusion/matches_predicate_spec.rb +48 -0
  47. data/spec/unit/knight/rule/inclusion/to_hash_spec.rb +12 -0
  48. data/spec/unit/knight/rule/maximum_length/class_methods/new_spec.rb +27 -0
  49. data/spec/unit/knight/rule/maximum_length/matches_predicate_spec.rb +21 -0
  50. data/spec/unit/knight/rule/maximum_length/to_hash_spec.rb +12 -0
  51. data/spec/unit/knight/rule/minimum_length/class_methods/new_spec.rb +27 -0
  52. data/spec/unit/knight/rule/minimum_length/matches_predicate_spec.rb +21 -0
  53. data/spec/unit/knight/rule/minimum_length/to_hash_spec.rb +12 -0
  54. data/spec/unit/knight/rule/presence/matches_predicate_spec.rb +27 -0
  55. data/spec/unit/knight/rule/range_length/class_methods/new_spec.rb +27 -0
  56. data/spec/unit/knight/rule/range_length/matches_predicate_spec.rb +19 -0
  57. data/spec/unit/knight/rule/range_length/to_hash_spec.rb +12 -0
  58. data/spec/unit/knight/rule/to_hash_spec.rb +13 -0
  59. data/spec/unit/knight/validator/add_spec.rb +29 -0
  60. data/spec/unit/knight/validator/class_methods/new_spec.rb +18 -0
  61. data/spec/unit/knight/validator/context_spec.rb +13 -0
  62. data/spec/unit/knight/validator/rules_spec.rb +29 -0
  63. data/spec/unit/knight/validator/run_spec.rb +26 -0
  64. metadata +138 -6
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::ExactLength, '#matches?' do
6
+ subject { rule.matches?(value) }
7
+
8
+ let(:rule) { described_class.new(:foo, 3) }
9
+ let(:value) { 'abc' }
10
+
11
+ it { should be_true }
12
+
13
+ %w(ab abcdef).each do |value|
14
+ context "with value: #{value.inspect}" do
15
+ let(:value) { value }
16
+ it { should be_false }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::ExactLength, '#to_hash' do
6
+ subject { object.to_hash }
7
+
8
+ let(:object) { described_class.new(:foo, 3) }
9
+
10
+ it { should be_frozen }
11
+ it { should eql({ attribute: :foo, length: 3 }) }
12
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::Format, '.new' do
6
+ let(:attribute) { :foo }
7
+ let(:regexp) { /abc/ }
8
+ let(:options) { { message: 'message' } }
9
+
10
+ context 'with options' do
11
+ subject { described_class.new(attribute, regexp, options) }
12
+
13
+ it { should be_instance_of(described_class) }
14
+ its(:attribute_name) { should eql(attribute) }
15
+ its(:regexp) { should eql(regexp) }
16
+ its(:options) { should eql(options) }
17
+ end
18
+
19
+ context 'with no options' do
20
+ subject { described_class.new(attribute, regexp) }
21
+
22
+ it { should be_instance_of(described_class) }
23
+ its(:options) { should be_empty }
24
+ its(:message) { should eql('%{attribute} has an invalid format') }
25
+ end
26
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::Format, '#matches?' do
6
+ subject { rule.matches?(value) }
7
+
8
+ let(:rule) { described_class.new(:foo, /abc/) }
9
+
10
+ %w(
11
+ abcxxx
12
+ xxxabc
13
+ xxxabcxxx
14
+ ).each do |value|
15
+ context "with value: #{value.inspect}" do
16
+ let(:value) { value }
17
+ it { should be_true }
18
+ end
19
+ end
20
+
21
+ %w(
22
+ bcxxx
23
+ xxxac
24
+ xxxabxxx
25
+ ).each do |value|
26
+ context "with value: #{value.inspect}" do
27
+ let(:value) { value }
28
+ it { should be_false }
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::Format, '#to_hash' do
6
+ subject { object.to_hash }
7
+
8
+ let(:object) { described_class.new(:foo, /abc/) }
9
+
10
+ it { should be_frozen }
11
+ it { should eql({ attribute: :foo, format: /abc/ }) }
12
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::Inclusion, '.new' do
6
+ subject { described_class.new(attribute, within) }
7
+
8
+ let(:attribute) { :foo }
9
+ let(:within) { 3..5 }
10
+ let(:options) { { message: 'message' } }
11
+
12
+ context 'with options' do
13
+ subject { described_class.new(attribute, within, options) }
14
+
15
+ it { should be_instance_of(described_class) }
16
+ its(:attribute_name) { should eql(attribute) }
17
+ its(:within) { should eql(within) }
18
+ its(:options) { should eql(options) }
19
+ end
20
+
21
+ context 'with no options' do
22
+ subject { described_class.new(attribute, within) }
23
+
24
+ it { should be_instance_of(described_class) }
25
+ its(:options) { should be_empty }
26
+ its(:message) { should eql('%{attribute} is not included in the list') }
27
+ end
28
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::Inclusion, '#matches?' do
6
+ subject { rule.matches?(value) }
7
+
8
+ let(:rule) { described_class.new(:foo, within) }
9
+
10
+ context 'Array' do
11
+ let(:within) { [1, 2, 3] }
12
+
13
+ describe 'matched' do
14
+ let(:value) { 5 }
15
+ it { should be_false }
16
+ end
17
+
18
+ describe 'not matched' do
19
+ let(:value) { 3 }
20
+ it { should be_true }
21
+ end
22
+ end
23
+
24
+ context 'Range' do
25
+ let(:within) { 1..3 }
26
+
27
+ describe 'matched' do
28
+ let(:value) { 5 }
29
+ it { should be_false }
30
+ end
31
+
32
+ describe 'not matched' do
33
+ let(:value) { 2 }
34
+ it { should be_true }
35
+ end
36
+ end
37
+
38
+ context 'cover? vs include?' do
39
+ let(:within) { double('within') }
40
+ let(:value) { 5 }
41
+
42
+ it 'send cover?' do
43
+ within.stub(:kind_of?).and_return(true)
44
+ within.should_receive(:cover?).with(value).and_return(false)
45
+ should be_false
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::Inclusion, '#to_hash' do
6
+ subject { object.to_hash }
7
+
8
+ let(:object) { described_class.new(:foo, [2, 4]) }
9
+
10
+ it { should be_frozen }
11
+ it { should eql({ attribute: :foo, within: [2, 4] }) }
12
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::MaximumLength, '.new' do
6
+
7
+ let(:attribute) { :foo }
8
+ let(:maximum) { 3 }
9
+ let(:options) { { message: 'message' } }
10
+
11
+ context 'with options' do
12
+ subject { described_class.new(attribute, maximum, options) }
13
+
14
+ it { should be_instance_of(described_class) }
15
+ its(:attribute_name) { should eql(attribute) }
16
+ its(:maximum) { should eql(maximum) }
17
+ its(:options) { should eql(options) }
18
+ end
19
+
20
+ context 'with no options' do
21
+ subject { described_class.new(attribute, maximum) }
22
+
23
+ it { should be_instance_of(described_class) }
24
+ its(:options) { should be_empty }
25
+ its(:message) { should eql('%{attribute} is too long') }
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::MaximumLength, '#matches?' do
6
+ subject { rule.matches?(value) }
7
+
8
+ let(:rule) { described_class.new(:foo, 3) }
9
+
10
+ %w(ab abc).each do |value|
11
+ context "with value: #{value.inspect}" do
12
+ let(:value) { value }
13
+ it { should be_true }
14
+ end
15
+ end
16
+
17
+ context 'longer' do
18
+ let(:value) { 'abcd' }
19
+ it { should be_false }
20
+ end
21
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::MaximumLength, '#to_hash' do
6
+ subject { object.to_hash }
7
+
8
+ let(:object) { described_class.new(:foo, 20) }
9
+
10
+ it { should be_frozen }
11
+ it { should eql({ attribute: :foo, maximum: 20 }) }
12
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::MinimumLength, '.new' do
6
+
7
+ let(:attribute) { :foo }
8
+ let(:minimum) { 3 }
9
+ let(:options) { { message: 'message' } }
10
+
11
+ context 'with options' do
12
+ subject { described_class.new(attribute, minimum, options) }
13
+
14
+ it { should be_instance_of(described_class) }
15
+ its(:attribute_name) { should eql(attribute) }
16
+ its(:minimum) { should eql(minimum) }
17
+ its(:options) { should eql(options) }
18
+ end
19
+
20
+ context 'with no options' do
21
+ subject { described_class.new(attribute, minimum) }
22
+
23
+ it { should be_instance_of(described_class) }
24
+ its(:options) { should be_empty }
25
+ its(:message) { should eql('%{attribute} is too short') }
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::MinimumLength, '#matches?' do
6
+ subject { rule.matches?(value) }
7
+
8
+ let(:rule) { described_class.new(:foo, 3) }
9
+
10
+ %w(abc abcd).each do |value|
11
+ context "with value: #{value.inspect}" do
12
+ let(:value) { value }
13
+ it { should be_true }
14
+ end
15
+ end
16
+
17
+ context 'shorter' do
18
+ let(:value) { 'ab' }
19
+ it { should be_false }
20
+ end
21
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::MinimumLength, '#to_hash' do
6
+ subject { object.to_hash }
7
+
8
+ let(:object) { described_class.new(:foo, 4) }
9
+
10
+ it { should be_frozen }
11
+ it { should eql({ attribute: :foo, minimum: 4 }) }
12
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::Presence, '#matches?' do
6
+ subject { rule.matches?(value) }
7
+
8
+ let(:rule) { described_class.new(:foo) }
9
+
10
+ [
11
+ nil,
12
+ '',
13
+ {},
14
+ [],
15
+ Set.new,
16
+ ].each do |value|
17
+ context "with value: #{value.inspect}" do
18
+ let(:value) { value }
19
+ it { should be_false }
20
+ end
21
+ end
22
+
23
+ context 'when the value is a string' do
24
+ let(:value) { 'bar' }
25
+ it { should be_true }
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::RangeLength, '.new' do
6
+
7
+ let(:attribute) { :foo }
8
+ let(:range) { 3..4 }
9
+ let(:options) { { message: 'message' } }
10
+
11
+ context 'with options' do
12
+ subject { described_class.new(attribute, range, options) }
13
+
14
+ it { should be_instance_of(described_class) }
15
+ its(:attribute_name) { should eql(attribute) }
16
+ its(:range) { should eql(range) }
17
+ its(:options) { should eql(options) }
18
+ end
19
+
20
+ context 'with no options' do
21
+ subject { described_class.new(attribute, range) }
22
+
23
+ it { should be_instance_of(described_class) }
24
+ its(:options) { should be_empty }
25
+ its(:message) { should eql('%{attribute} has an invalid length') }
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::RangeLength, '#matches?' do
6
+ subject { rule.matches?(value) }
7
+
8
+ let(:rule) { described_class.new(:foo, 3..5) }
9
+ let(:value) { 'abc' }
10
+
11
+ it { should be_true }
12
+
13
+ %w(ab abcdef).each do |value|
14
+ context "with value: #{value.inspect}" do
15
+ let(:value) { value }
16
+ it { should be_false }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule::RangeLength, '#to_hash' do
6
+ subject { object.to_hash }
7
+
8
+ let(:object) { described_class.new(:foo, (4...6)) }
9
+
10
+ it { should be_frozen }
11
+ it { should eql({ attribute: :foo, minimum: 4, maximum: 5 }) }
12
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rule, '#to_hash' do
6
+ subject { object.to_hash }
7
+
8
+ let(:described_class) { Class.new(Rule) }
9
+ let(:object) { described_class.new(:foo) }
10
+
11
+ it { should be_frozen }
12
+ it { should eql({ attribute: :foo }) }
13
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Validator, '#add' do
6
+ subject { validator.rules(context) }
7
+
8
+ let(:validator) { described_class.new(rule1) }
9
+ let(:rule1) { Rule::ExactLength.new(:username, 10) }
10
+ let(:rule2) { Rule::Presence.new(:username) }
11
+
12
+ before do
13
+ validator.add(rule2, :register)
14
+ validator.add(rule2)
15
+ validator.add(nil)
16
+ end
17
+
18
+ context 'default_context' do
19
+ let(:context) { :default }
20
+ specify { expect(subject.size).to eql(2) }
21
+ specify { expect(subject).to eql(Set.new([rule1, rule2])) }
22
+ end
23
+
24
+ context 'register' do
25
+ let(:context) { :register }
26
+ specify { expect(subject.size).to eql(1) }
27
+ specify { expect(subject).to eql(Set.new([rule2])) }
28
+ end
29
+ end