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 ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
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
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in valid_attribute.gemspec
4
+ gemspec
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,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,3 @@
1
+ module ValidAttribute
2
+ VERSION = "0.0.1"
3
+ end
@@ -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
+
@@ -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