valid_attribute 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.
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/README.markdown +61 -0
- data/Rakefile +2 -0
- data/lib/valid_attribute/version.rb +3 -0
- data/lib/valid_attribute.rb +73 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/valid_attribute_spec.rb +120 -0
- data/valid_attribute.gemspec +29 -0
- metadata +100 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create default@valid_attribute > /dev/null
|
data/Gemfile
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# ValidAttribute #
|
2
|
+
|
3
|
+
ValidAttribute is a minimalist framework for validation BDD.
|
4
|
+
|
5
|
+
## Installation ##
|
6
|
+
|
7
|
+
If you're using Rails just add the library to your Gemfile
|
8
|
+
|
9
|
+
gem 'valid_attribute'
|
10
|
+
|
11
|
+
Then add it to your spec_helper
|
12
|
+
|
13
|
+
require 'valid_attribute'
|
14
|
+
|
15
|
+
## Usage ##
|
16
|
+
|
17
|
+
Instead of having validation specific matchers ValidAttribute only cares if the attribute is valid under certain circumstances
|
18
|
+
|
19
|
+
class User
|
20
|
+
include ActiveModel::Validations
|
21
|
+
|
22
|
+
attr_accessor :email, :name, :password
|
23
|
+
|
24
|
+
validates :email, :format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :message => 'invalid email format' }
|
25
|
+
validates :name, :length => { :minimum => 5 }
|
26
|
+
validates :password, :confirmation => true, :presence => true
|
27
|
+
end
|
28
|
+
|
29
|
+
describe User do
|
30
|
+
# The .with method can take any number of values that you want to pass
|
31
|
+
it { should have_valid(:email).with('test@test.com', 'test+spam@gmail.com') }
|
32
|
+
it { should_not have_valid(:email).with('fail', 123).message('invalid email format') }
|
33
|
+
it { should have_valid(:name).with('TestName')
|
34
|
+
it { should_not have_valid(:name).with('Test')
|
35
|
+
|
36
|
+
# Because 'should' works off the the 'subject' in RSpec we can set other values if necessary for a given validation test
|
37
|
+
describe 'password' do
|
38
|
+
before { subject.password_confirmation = 'password' }
|
39
|
+
it { should have_valid(:password).with('password') }
|
40
|
+
# Not providing '.with' defaults to nil
|
41
|
+
it { should_not have_valid(:password) }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
## Non-ActiveModel models ##
|
46
|
+
|
47
|
+
As long as your model responds to the following methods:
|
48
|
+
|
49
|
+
* valid? - only used to generate errors on the model
|
50
|
+
* errors - should be a Hash of errors, the keys being the attribute with errors and the value for each key being an array of error messages
|
51
|
+
* model_name - used in the failure messages. Class level method
|
52
|
+
|
53
|
+
Other than that everything should work!
|
54
|
+
|
55
|
+
## Legal ##
|
56
|
+
|
57
|
+
Brian Cardarella © 2011
|
58
|
+
|
59
|
+
[@bcardarella](http://twitter.com/bcardarella)
|
60
|
+
|
61
|
+
[Licensed under the MIT license](http://www.opensource.org/licenses/mit-license.php)
|
data/Rakefile
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
module ValidAttribute
|
2
|
+
|
3
|
+
def have_valid(attr)
|
4
|
+
ValidAttributeMatcher.new(attr)
|
5
|
+
end
|
6
|
+
|
7
|
+
class ValidAttributeMatcher
|
8
|
+
attr_accessor :attr, :values, :validation_message, :subject, :failed_value
|
9
|
+
|
10
|
+
def initialize(attr)
|
11
|
+
self.attr = attr
|
12
|
+
self.values = [nil]
|
13
|
+
end
|
14
|
+
|
15
|
+
def with(*values)
|
16
|
+
self.values = values
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def message(message)
|
21
|
+
self.validation_message = message
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def negative_failure_message
|
26
|
+
failure_message = " expected #{subject.class.model_name}##{attr} to not accept a value of #{value_message}"
|
27
|
+
|
28
|
+
if validation_message
|
29
|
+
failure_message = "#{failure_message} with a message of '#{validation_message}'"
|
30
|
+
end
|
31
|
+
|
32
|
+
failure_message
|
33
|
+
end
|
34
|
+
|
35
|
+
def failure_message
|
36
|
+
" expected #{subject.class.model_name}##{attr} to accept a value of #{value_message}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def value_message
|
40
|
+
if failed_value.is_a?(String)
|
41
|
+
"'#{failed_value}'"
|
42
|
+
else
|
43
|
+
failed_value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def matches?(subject)
|
48
|
+
self.subject = subject
|
49
|
+
|
50
|
+
values.each do |value|
|
51
|
+
subject.send("#{attr}=", value)
|
52
|
+
subject.valid?
|
53
|
+
|
54
|
+
if subject.errors.include?(attr)
|
55
|
+
self.failed_value = value
|
56
|
+
if validation_message
|
57
|
+
return !subject.errors[attr].include?(validation_message)
|
58
|
+
else
|
59
|
+
return false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
true
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
module RSpec::Matchers
|
71
|
+
include ValidAttribute
|
72
|
+
end if defined?(RSpec)
|
73
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.setup
|
4
|
+
|
5
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
require 'ruby-debug'
|
8
|
+
require 'valid_attribute'
|
9
|
+
require 'rspec'
|
10
|
+
require 'rspec/autorun'
|
11
|
+
require 'bourne'
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.mock_with :mocha
|
15
|
+
end
|
16
|
+
|
17
|
+
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class Should
|
4
|
+
include ValidAttribute
|
5
|
+
end
|
6
|
+
|
7
|
+
class User
|
8
|
+
attr_accessor :name
|
9
|
+
|
10
|
+
def errors
|
11
|
+
@error ||= {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.model_name
|
15
|
+
'User'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'ValidAttribute' do
|
20
|
+
|
21
|
+
before do
|
22
|
+
@should = Should.new
|
23
|
+
@user = User.new
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'valid data' do
|
27
|
+
before do
|
28
|
+
@user.stubs(:valid?).returns(true)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'passes with no value set' do
|
32
|
+
matcher = @should.have_valid(:name)
|
33
|
+
matcher.matches?(@user).should be_true
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'passes with values set' do
|
37
|
+
matcher = @should.have_valid(:name).with('Brian', 'Stephanie')
|
38
|
+
matcher.matches?(@user).should be_true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'invalid data' do
|
43
|
+
before do
|
44
|
+
@user.stubs(:valid?).returns(false)
|
45
|
+
@user.errors[:name] = ['is not valid']
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'returns false when no message passed' do
|
49
|
+
matcher = @should.have_valid(:name)
|
50
|
+
matcher.matches?(@user).should be_false
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'returns true when wrong message is passed' do
|
54
|
+
matcher = @should.have_valid(:name).message('wrong message')
|
55
|
+
matcher.matches?(@user).should_not be_false
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'returns false when correct message is passed' do
|
59
|
+
matcher = @should.have_valid(:name).message('is not valid')
|
60
|
+
matcher.matches?(@user).should be_false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'data is first valid then invalid' do
|
65
|
+
before do
|
66
|
+
@user.stubs(:valid?).returns(true).then.returns(false)
|
67
|
+
@user.errors[:name] = ['is not valid']
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'returns false' do
|
71
|
+
matcher = @should.have_valid(:name).with('true', 'false')
|
72
|
+
matcher.matches?(@user).should be_false
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe 'failure message' do
|
77
|
+
before do
|
78
|
+
@user.stubs(:valid?).returns(false)
|
79
|
+
@user.errors[:name] = ['is not valid']
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'has a message for string values' do
|
83
|
+
matcher = @should.have_valid(:name).with('Brian')
|
84
|
+
matcher.matches?(@user)
|
85
|
+
matcher.failure_message.should == " expected User#name to accept a value of 'Brian'"
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'has a message for non string values' do
|
89
|
+
matcher = @should.have_valid(:name).with(123)
|
90
|
+
matcher.matches?(@user)
|
91
|
+
matcher.failure_message.should == " expected User#name to accept a value of 123"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe 'negative failure message' do
|
96
|
+
before do
|
97
|
+
@user.stubs(:valid?).returns(false)
|
98
|
+
@user.errors[:name] = ['is not valid']
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'has a message for string values' do
|
102
|
+
matcher = @should.have_valid(:name).with('Brian')
|
103
|
+
matcher.matches?(@user)
|
104
|
+
matcher.negative_failure_message.should == " expected User#name to not accept a value of 'Brian'"
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'has a message for non string values' do
|
108
|
+
matcher = @should.have_valid(:name).with(123)
|
109
|
+
matcher.matches?(@user)
|
110
|
+
matcher.negative_failure_message.should == " expected User#name to not accept a value of 123"
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'includes the validation message' do
|
114
|
+
matcher = @should.have_valid(:name).with('Brian').message('is not valid')
|
115
|
+
matcher.matches?(@user)
|
116
|
+
matcher.negative_failure_message.should == " expected User#name to not accept a value of 'Brian' with a message of 'is not valid'"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "valid_attribute/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "valid_attribute"
|
7
|
+
s.version = ValidAttribute::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Brian Cardarella"]
|
10
|
+
s.email = ["bcardarella@gmail.com"]
|
11
|
+
s.homepage = "https://github.com/bcardarella/valid_attribute"
|
12
|
+
s.summary = %q{Minimalist validation matcher framework}
|
13
|
+
s.description = %q{Minimalist validation matcher framework}
|
14
|
+
|
15
|
+
s.rubyforge_project = "valid_attribute"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_development_dependency 'rspec'
|
23
|
+
s.add_development_dependency 'bourne'
|
24
|
+
if RUBY_VERSION >= '1.9'
|
25
|
+
s.add_development_dependency 'ruby-debug19'
|
26
|
+
else
|
27
|
+
s.add_development_dependency 'ruby-debug'
|
28
|
+
end
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: valid_attribute
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Brian Cardarella
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-04-04 00:00:00 -04:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rspec
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
type: :development
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bourne
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "0"
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: ruby-debug19
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id003
|
49
|
+
description: Minimalist validation matcher framework
|
50
|
+
email:
|
51
|
+
- bcardarella@gmail.com
|
52
|
+
executables: []
|
53
|
+
|
54
|
+
extensions: []
|
55
|
+
|
56
|
+
extra_rdoc_files: []
|
57
|
+
|
58
|
+
files:
|
59
|
+
- .gitignore
|
60
|
+
- .rspec
|
61
|
+
- .rvmrc
|
62
|
+
- Gemfile
|
63
|
+
- README.markdown
|
64
|
+
- Rakefile
|
65
|
+
- lib/valid_attribute.rb
|
66
|
+
- lib/valid_attribute/version.rb
|
67
|
+
- spec/spec_helper.rb
|
68
|
+
- spec/valid_attribute_spec.rb
|
69
|
+
- valid_attribute.gemspec
|
70
|
+
has_rdoc: true
|
71
|
+
homepage: https://github.com/bcardarella/valid_attribute
|
72
|
+
licenses: []
|
73
|
+
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: "0"
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: "0"
|
91
|
+
requirements: []
|
92
|
+
|
93
|
+
rubyforge_project: valid_attribute
|
94
|
+
rubygems_version: 1.5.3
|
95
|
+
signing_key:
|
96
|
+
specification_version: 3
|
97
|
+
summary: Minimalist validation matcher framework
|
98
|
+
test_files:
|
99
|
+
- spec/spec_helper.rb
|
100
|
+
- spec/valid_attribute_spec.rb
|