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