Skip to content

Commit

Permalink
Merge pull request #13 from mcorp/validate_length_of
Browse files Browse the repository at this point in the history
Matcher to validate size of attribute (resolves #11)
  • Loading branch information
vyper committed Jun 30, 2015
2 parents 52f3fbc + 9c1d937 commit c4d73a6
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 2 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,23 @@ class Person
include Lotus::Validations

attribute :email, presence: true, format: /@/
attribute :name, size: 5..50
attribute :password, size: 10
end
```

### Spec
```ruby
# allow_value
it { is_expected.to allow_value("leo@nospam.org").for(:email) }
it { is_expected.to_not allow_value('leo-at-nospam.org').for(:email) }
it { is_expected.to validate_presence_of(:name) }

# presence
it { is_expected.to validate_presence_of(:email) }

# size
it { is_expected.to validate_length(:name).is_at_least(5).is_at_most(50) }
it { is_expected.to validate_length(:password).is_equal_to(10) }
```

## Contributing
Expand Down
1 change: 1 addition & 0 deletions lib/shoulda/lotus/matchers.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'shoulda/lotus/matchers/allow_value_matcher'
require 'shoulda/lotus/matchers/validate_length_of_matcher'
require 'shoulda/lotus/matchers/validate_presence_of_matcher'

module Shoulda
Expand Down
68 changes: 68 additions & 0 deletions lib/shoulda/lotus/matchers/validate_length_of_matcher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
module Shoulda
module Lotus
module Matchers
def validate_length_of(attribute)
ValidateLengthOfMatcher.new(attribute)
end

class ValidateLengthOfMatcher
def initialize(attribute)
@attribute = attribute
end

def matches?(target)
errors = []

@target = target

@target.send("#{@attribute}=", '*' * (minimum - 1))
@target.valid?
errors << (@target.errors.for(@attribute).select { |error| error.attribute == @attribute.to_s && error.validation == :size }.size > 0)

@target.send("#{@attribute}=", '*' * (maximum + 1))
@target.valid?
errors << (@target.errors.for(@attribute).select { |error| error.attribute == @attribute.to_s && error.validation == :size }.size > 0)

errors.all? { |error| error }
end

def description
"'#{@attribute}' size between '#{@minimum}..#{@maximum}'"
end

def failure_message
"'#{@attribute}' is not between '#{@minimum}..#{@maximum}'"
end

def failure_message_when_negated
"'#{@attribute}' is between '#{@minimum}..#{@maximum}'"
end

def is_at_least(minimum)
@minimum = minimum
self
end

def is_at_most(maximum)
@maximum = maximum
self
end

def is_equal_to(limit)
@minimum, @maximum = limit
self
end

private

def minimum
@minimum ||= 1
end

def maximum
@maximum ||= 1
end
end
end
end
end
2 changes: 1 addition & 1 deletion lib/shoulda/lotus/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Shoulda
module Lotus
VERSION = '0.0.2'.freeze
VERSION = '0.0.3'.freeze
end
end
6 changes: 6 additions & 0 deletions spec/fixtures/with_validation_length_model.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class WithValidationLengthModel
include Lotus::Validations

attribute :name_equal_10, size: 10
attribute :name_between_1_10, size: 1..10
end
35 changes: 35 additions & 0 deletions spec/shoulda/matchers/validate_length_of_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require 'spec_helper'

RSpec.describe Shoulda::Lotus::Matchers::ValidateLengthOfMatcher do
include Shoulda::Lotus::Matchers

it '#description' do
matcher = validate_length_of(:bar).is_at_least(1).is_at_most(10)

expect(matcher.description).to eq "'bar' size between '1..10'"
end

context 'an attribute with a validation' do
let(:model) { WithValidationLengthModel.new }

it 'accepts an exact' do
expect(model).to validate_length_of(:name_equal_10).is_equal_to(10)
end

it 'accepts an interval' do
expect(model).to validate_length_of(:name_between_1_10).is_at_least(1).is_at_most(10)
end

it 'provides correct failure message'
end

context 'an attribute without validation' do
let(:model) { WithoutValidationModel.new }

it 'does not validate' do
expect(model).to_not validate_length_of(:email)
end

it 'provides correct failure message'
end
end
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@

require 'fixtures/without_validation_model'
require 'fixtures/with_validation_format_model'
require 'fixtures/with_validation_length_model'
require 'fixtures/with_validation_presence_model'

0 comments on commit c4d73a6

Please sign in to comment.