accept_values_for 0.4.3 → 0.5.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/.travis.yml +24 -0
- data/Gemfile +18 -6
- data/LICENSE +19 -0
- data/Rakefile +3 -0
- data/Readme.md +49 -0
- data/VERSION +1 -1
- data/accept_values_for.gemspec +21 -26
- data/lib/accept_values_for.rb +31 -27
- data/lib/discover.rb +4 -124
- data/spec/accept_values_for_spec.rb +61 -15
- data/spec/discover_spec.rb +0 -37
- data/spec/spec_helper.rb +7 -8
- metadata +110 -117
- data/Gemfile.lock +0 -75
- data/Readme.textile +0 -82
data/.travis.yml
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
language: ruby
|
2
|
+
env:
|
3
|
+
- "RAILS_VERSION=3.0.0"
|
4
|
+
- "RAILS_VERSION=3.1.0"
|
5
|
+
- "RAILS_VERSION=3.2.0"
|
6
|
+
- "RAILS_VERSION=4.0.0"
|
7
|
+
rvm:
|
8
|
+
- 1.8.7
|
9
|
+
- 1.9.2
|
10
|
+
- 1.9.3
|
11
|
+
- 2.0.0
|
12
|
+
matrix:
|
13
|
+
exclude:
|
14
|
+
- rvm: 1.8.7
|
15
|
+
env: "RAILS_VERSION=4.0.0"
|
16
|
+
- rvm: 1.9.2
|
17
|
+
env: "RAILS_VERSION=4.0.0"
|
18
|
+
notifications:
|
19
|
+
email:
|
20
|
+
- agresso@gmail.com
|
21
|
+
branches:
|
22
|
+
only:
|
23
|
+
- master
|
24
|
+
|
data/Gemfile
CHANGED
@@ -1,10 +1,22 @@
|
|
1
|
-
source
|
2
|
-
gem 'activemodel', '>=3.0.0'
|
3
|
-
gem "rspec", ">=0"
|
1
|
+
source 'https://rubygems.org'
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
rails_version = ENV['RAILS_VERSION'] || 'default'
|
4
|
+
|
5
|
+
rails = case rails_version
|
6
|
+
when 'master'
|
7
|
+
{ :github => 'rails/rails'}
|
8
|
+
when "default"
|
9
|
+
'~> 3.2.0'
|
10
|
+
else
|
11
|
+
"~> #{rails_version}"
|
12
|
+
end
|
13
|
+
|
14
|
+
gem 'activemodel', rails
|
15
|
+
|
16
|
+
group :development, :test do
|
17
|
+
gem 'rspec', '>=0'
|
18
|
+
gem 'rails', rails
|
19
|
+
gem 'rspec-rails', '>=2.0.0'
|
8
20
|
gem 'jeweler'
|
9
21
|
gem 'sqlite3-ruby'
|
10
22
|
end
|
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2012 Bogdan Gusiev
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is furnished
|
8
|
+
to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/Rakefile
CHANGED
data/Readme.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Accept values for
|
2
|
+
|
3
|
+
## Description
|
4
|
+
|
5
|
+
This gem provides an rspec matcher that helps you to test ActiveModel validation.
|
6
|
+
|
7
|
+
*NOTE:* `discover` matcher that was previously here was extracted to its own gem
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
[RSpec matcher to test the validation](http://gusiev.com/2010/06/ultimate-rspec-matcher-to-test-validation/)
|
12
|
+
|
13
|
+
``` ruby
|
14
|
+
describe User do
|
15
|
+
|
16
|
+
subject { User.new(@valid_attributes)}
|
17
|
+
|
18
|
+
it { should accept_values_for(:email, "john@example.com", "lambda@gusiev.com") }
|
19
|
+
it { should_not accept_values_for(:email, "invalid", nil, "a@b", "john@.com") }
|
20
|
+
end
|
21
|
+
```
|
22
|
+
|
23
|
+
You can specify which values should be accepted by model as valid and which values should not be accepted as invalid.
|
24
|
+
|
25
|
+
|
26
|
+
## Dependencies
|
27
|
+
|
28
|
+
* ActiveModel
|
29
|
+
* Rspec
|
30
|
+
|
31
|
+
## Install
|
32
|
+
|
33
|
+
|
34
|
+
### Gemfile
|
35
|
+
|
36
|
+
``` ruby
|
37
|
+
group :test do
|
38
|
+
gem 'accept_values_for'
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
|
43
|
+
## Self-Promotion
|
44
|
+
|
45
|
+
Like accept\_values\_for?
|
46
|
+
|
47
|
+
Follow the repository on [GitHub](https://github.com/bogdan/accept_values_for).
|
48
|
+
|
49
|
+
Read [author blog](http://gusiev.com).
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.1
|
data/accept_values_for.gemspec
CHANGED
@@ -4,23 +4,24 @@
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
8
|
-
s.version = "0.
|
7
|
+
s.name = "accept_values_for"
|
8
|
+
s.version = "0.5.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Bogdan Gusiev"]
|
12
|
-
s.date =
|
13
|
-
s.description =
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
s.date = "2013-10-20"
|
13
|
+
s.description = "Rspec: When you have a complex validation(e.g. regexp or custom method) on ActiveRecord model\nyou have to write annoying easy specs on which values should be accepted by your validation method and which should not.\naccepts_values_for rspec matcher simplify the code. See example for more information.\n"
|
14
|
+
s.email = "agresso@gmail.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE"
|
17
|
+
]
|
18
18
|
s.files = [
|
19
|
+
".travis.yml",
|
19
20
|
"Changelog.textile",
|
20
21
|
"Gemfile",
|
21
|
-
"
|
22
|
+
"LICENSE",
|
22
23
|
"Rakefile",
|
23
|
-
"Readme.
|
24
|
+
"Readme.md",
|
24
25
|
"VERSION",
|
25
26
|
"accept_values_for.gemspec",
|
26
27
|
"lib/accept_values_for.rb",
|
@@ -29,39 +30,33 @@ accepts_values_for rspec matcher simplify the code. See example for more informa
|
|
29
30
|
"spec/discover_spec.rb",
|
30
31
|
"spec/spec_helper.rb"
|
31
32
|
]
|
32
|
-
s.homepage =
|
33
|
+
s.homepage = "http://github.com/bogdan/accept_values_for"
|
33
34
|
s.require_paths = ["lib"]
|
34
|
-
s.rubygems_version =
|
35
|
-
s.summary =
|
36
|
-
s.test_files = [
|
37
|
-
"spec/accept_values_for_spec.rb",
|
38
|
-
"spec/discover_spec.rb",
|
39
|
-
"spec/spec_helper.rb"
|
40
|
-
]
|
35
|
+
s.rubygems_version = "1.8.24"
|
36
|
+
s.summary = "In order to test a complex validation for ActiveRecord models Implemented accept_values_for custom rspec matcher"
|
41
37
|
|
42
38
|
if s.respond_to? :specification_version then
|
43
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
44
39
|
s.specification_version = 3
|
45
40
|
|
46
41
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
47
|
-
s.add_runtime_dependency(%q<activemodel>, ["
|
48
|
-
s.
|
49
|
-
s.add_development_dependency(%q<
|
42
|
+
s.add_runtime_dependency(%q<activemodel>, ["~> 3.2.0"])
|
43
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
44
|
+
s.add_development_dependency(%q<rails>, ["~> 3.2.0"])
|
50
45
|
s.add_development_dependency(%q<rspec-rails>, [">= 2.0.0"])
|
51
46
|
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
52
47
|
s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
|
53
48
|
else
|
54
|
-
s.add_dependency(%q<activemodel>, ["
|
49
|
+
s.add_dependency(%q<activemodel>, ["~> 3.2.0"])
|
55
50
|
s.add_dependency(%q<rspec>, [">= 0"])
|
56
|
-
s.add_dependency(%q<
|
51
|
+
s.add_dependency(%q<rails>, ["~> 3.2.0"])
|
57
52
|
s.add_dependency(%q<rspec-rails>, [">= 2.0.0"])
|
58
53
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
59
54
|
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
60
55
|
end
|
61
56
|
else
|
62
|
-
s.add_dependency(%q<activemodel>, ["
|
57
|
+
s.add_dependency(%q<activemodel>, ["~> 3.2.0"])
|
63
58
|
s.add_dependency(%q<rspec>, [">= 0"])
|
64
|
-
s.add_dependency(%q<
|
59
|
+
s.add_dependency(%q<rails>, ["~> 3.2.0"])
|
65
60
|
s.add_dependency(%q<rspec-rails>, [">= 2.0.0"])
|
66
61
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
67
62
|
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
data/lib/accept_values_for.rb
CHANGED
@@ -31,58 +31,62 @@ class AcceptValuesFor #:nodoc:
|
|
31
31
|
def initialize(attribute, *values)
|
32
32
|
@attribute = attribute
|
33
33
|
@values = values
|
34
|
-
|
34
|
+
@failed_values = {}
|
35
35
|
end
|
36
36
|
|
37
37
|
def matches?(model)
|
38
|
-
|
39
|
-
return false unless model.class.included_modules.include?(ActiveModel::Validations)
|
40
|
-
old_value = @model.send(@attribute)
|
41
|
-
@values.each do |value|
|
42
|
-
model.send("#{@attribute}=", value)
|
43
|
-
model.valid?
|
38
|
+
base_matches?(model) do |value|
|
44
39
|
unless model.errors[@attribute].to_a.empty?
|
45
|
-
@
|
46
|
-
return false
|
40
|
+
@failed_values[value] = Array(model.errors[@attribute]).join(", ")
|
47
41
|
end
|
48
42
|
end
|
49
|
-
return true
|
50
|
-
ensure
|
51
|
-
@model.send("#{@attribute}=", old_value) if defined?(old_value)
|
52
43
|
end
|
53
44
|
|
54
45
|
def does_not_match?(model)
|
55
|
-
|
56
|
-
return false unless model.class.included_modules.include?(ActiveModel::Validations)
|
57
|
-
old_value = @model.send(@attribute)
|
58
|
-
@values.each do |value|
|
59
|
-
model.send("#{@attribute}=", value)
|
60
|
-
model.valid?
|
46
|
+
base_matches?(model) do |value|
|
61
47
|
if model.errors[@attribute].to_a.empty?
|
62
|
-
@
|
63
|
-
return false
|
48
|
+
@failed_values[value] = nil
|
64
49
|
end
|
65
50
|
end
|
66
|
-
return true
|
67
|
-
ensure
|
68
|
-
@model.send("#{@attribute}=", old_value) if defined?(old_value)
|
69
51
|
end
|
70
52
|
|
71
53
|
def failure_message_for_should
|
72
|
-
result = "expected #{@model.inspect} to accept
|
73
|
-
|
74
|
-
result
|
54
|
+
result = "expected #{@model.inspect} to accept values #{formatted_failed_values} for #{@attribute.inspect}, but it was not\n"
|
55
|
+
@failed_values.keys.sort.each do |key|
|
56
|
+
result << "\nValue: #{key}\tErrors: #{@attribute} #{@failed_values[key]}"
|
75
57
|
end
|
76
58
|
result
|
77
59
|
end
|
78
60
|
|
79
61
|
def failure_message_for_should_not
|
80
|
-
"expected #{@model.inspect} to not accept
|
62
|
+
"expected #{@model.inspect} to not accept values #{formatted_failed_values} for #{@attribute.inspect} attribute, but was"
|
81
63
|
end
|
82
64
|
|
83
65
|
def description
|
84
66
|
"accept values #{@values.map(&:inspect).join(', ')} for #{@attribute.inspect} attribute"
|
85
67
|
end
|
86
68
|
|
69
|
+
private
|
70
|
+
def base_matches?(model)
|
71
|
+
@model = model
|
72
|
+
!has_validations_module?(model) and return false
|
73
|
+
old_value = @model.send(@attribute)
|
74
|
+
@values.each do |value|
|
75
|
+
model.send("#@attribute=", value)
|
76
|
+
model.valid?
|
77
|
+
yield(value) if @model.respond_to?(:errors) && @model.errors.is_a?(ActiveModel::Errors)
|
78
|
+
end
|
79
|
+
return @failed_values.empty?
|
80
|
+
ensure
|
81
|
+
@model.send("#@attribute=", old_value) if defined?(old_value)
|
82
|
+
end
|
83
|
+
|
84
|
+
def has_validations_module?(model)
|
85
|
+
model.class.included_modules.include?(ActiveModel::Validations)
|
86
|
+
end
|
87
|
+
|
88
|
+
def formatted_failed_values
|
89
|
+
@failed_values.keys.sort.map(&:inspect).join(", ")
|
90
|
+
end
|
87
91
|
end
|
88
92
|
|
data/lib/discover.rb
CHANGED
@@ -1,127 +1,7 @@
|
|
1
|
-
if defined?(ActiveRecord)
|
2
|
-
|
3
|
-
|
4
|
-
# Implemented discover custom matcher
|
5
|
-
#
|
6
|
-
# :call-seq:
|
7
|
-
# Class.named_scope.should discover(model1, model2)
|
8
|
-
# Class.named_scope.should_not discover(model3, model4)
|
9
|
-
#
|
10
|
-
# matcher subject should be an instance of ActiverRecord::NamedScope::Scoped or Array
|
11
|
-
# models should be an instace of ActiverRecord::Base
|
12
|
-
#
|
13
|
-
# Use this if you need to check the inclution of objects ActiveRecord finders result
|
14
|
-
# and it's order
|
15
|
-
#
|
16
|
-
# == Examples
|
17
|
-
#
|
18
|
-
# class Group < AR::Base
|
19
|
-
# named_scope :approved, :conditions => "approved = true"
|
20
|
-
# named_scope :order_by_name, :order => "name"
|
21
|
-
# end
|
22
|
-
#
|
23
|
-
# Group.approved.should discover(Group.create!(:approved => true))
|
24
|
-
# Group.approved.should_not discover(Group.create!(:approved => false))
|
25
|
-
# Group.order_by_name.should discover(Group.create!(:name => "apple"), Group.create!(:name => "bear").with_exact_order)
|
26
|
-
#
|
27
|
-
#
|
28
|
-
def discover(*objects)
|
29
|
-
Rspec::Discover.new(*objects)
|
1
|
+
if defined?(ActiveRecord) && !respond_to?(:discover)
|
2
|
+
def discover(*objects) #:nodoc:
|
3
|
+
include(*objects)
|
30
4
|
end
|
31
|
-
|
5
|
+
warn "#discover matcher was removed from accept_values_for. Use gem discover instead"
|
32
6
|
end
|
33
7
|
|
34
|
-
module Rspec
|
35
|
-
class Discover #:nodoc:
|
36
|
-
|
37
|
-
def initialize(*objects)
|
38
|
-
@objects = objects
|
39
|
-
end
|
40
|
-
|
41
|
-
def with_exact_order
|
42
|
-
@with_exact_order = true
|
43
|
-
self
|
44
|
-
end
|
45
|
-
|
46
|
-
def matches?(scope)
|
47
|
-
@scope = scope
|
48
|
-
return valid_findness? && valid_indexes?
|
49
|
-
end
|
50
|
-
|
51
|
-
def does_not_match?(scope)
|
52
|
-
@scope = scope
|
53
|
-
if @with_exact_order
|
54
|
-
raise "calling #with_exact_order is not allowed with should_not match"
|
55
|
-
end
|
56
|
-
return valid_not_findness?
|
57
|
-
end
|
58
|
-
|
59
|
-
def failure_message_for_should
|
60
|
-
result = @not_found_object_ids.any? ?
|
61
|
-
"expected #{@scope.inspect} to include objects: #{@not_found_object_ids.inspect}" :
|
62
|
-
"expected #{@scope.inspect} to be ordered as: #{@objects.map(&:id).inspect}"
|
63
|
-
result += ", but it was not. "
|
64
|
-
if @not_found_object_ids.any?
|
65
|
-
result += found_objects_string
|
66
|
-
end
|
67
|
-
result
|
68
|
-
end
|
69
|
-
|
70
|
-
def failure_message_for_should_not
|
71
|
-
result = "expected #{@scope.inspect} to not include objects: #{@found_object_ids.inspect}"
|
72
|
-
result += ", but it was. "
|
73
|
-
result += found_objects_string
|
74
|
-
result
|
75
|
-
end
|
76
|
-
|
77
|
-
|
78
|
-
def description
|
79
|
-
"discover #{@objects.map(&:inspect).join(', ')} " + ordering_string
|
80
|
-
end
|
81
|
-
|
82
|
-
protected
|
83
|
-
|
84
|
-
def valid_findness?
|
85
|
-
result = true
|
86
|
-
@not_found_object_ids = []
|
87
|
-
@objects.each do |object|
|
88
|
-
unless @scope.include?(object)
|
89
|
-
@not_found_object_ids << object.id
|
90
|
-
result = false
|
91
|
-
end
|
92
|
-
end
|
93
|
-
result
|
94
|
-
end
|
95
|
-
|
96
|
-
|
97
|
-
def valid_indexes?
|
98
|
-
return true unless @with_exact_order
|
99
|
-
indexes = @objects.map{|o| @scope.index(o)}
|
100
|
-
return indexes.sort == indexes
|
101
|
-
end
|
102
|
-
|
103
|
-
def valid_not_findness?
|
104
|
-
result = true
|
105
|
-
@found_object_ids = []
|
106
|
-
@objects.each do |object|
|
107
|
-
if @scope.include?(object)
|
108
|
-
@found_object_ids << object.id
|
109
|
-
result = false
|
110
|
-
end
|
111
|
-
end
|
112
|
-
result
|
113
|
-
end
|
114
|
-
|
115
|
-
def found_objects_string
|
116
|
-
"Found objects: " + @scope.map(&:id).inspect
|
117
|
-
end
|
118
|
-
|
119
|
-
|
120
|
-
def ordering_string
|
121
|
-
@with_exact_order ? "with exact order" : ""
|
122
|
-
end
|
123
|
-
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
|
@@ -1,29 +1,75 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "AcceptValuesFor" do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
it "should have custom condition for should_not" do
|
8
|
-
accept_values_for(:gender, "INVALID", "MALE").does_not_match?(subject).should be_false
|
9
|
-
end
|
4
|
+
let(:person) { Person.new(:gender => "MALE", :group => Group.new(:name => "Primary")) }
|
5
|
+
let(:accept_values_for_object) { accept_values_for(:gender, *values) }
|
10
6
|
|
11
7
|
describe "#matches?" do
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
8
|
+
subject { accept_values_for_object.matches?(person) }
|
9
|
+
context "when value is accepted" do
|
10
|
+
let(:values) { ['MALE'] }
|
11
|
+
it { should be_true }
|
12
|
+
end
|
13
|
+
context "when value is not accepted" do
|
14
|
+
let(:values) { ['INVALID'] }
|
15
|
+
it { should be_false }
|
16
|
+
it "should have correct failure message for should" do
|
17
|
+
accept_values_for_object.matches?(person)
|
18
|
+
accept_values_for_object.failure_message_for_should.should == "expected #{person.inspect} to accept values \"INVALID\" for :gender, but it was not\n\nValue: INVALID\tErrors: gender is not included in the list"
|
19
|
+
end
|
20
|
+
it "should assign the old value for attribute" do
|
21
|
+
accept_values_for_object.matches?(person)
|
22
|
+
person.gender.should == 'MALE'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
context "when 2 values are not accepted" do
|
26
|
+
let(:values) { ["INVALID", "WRONG"] }
|
27
|
+
it { should be_false }
|
28
|
+
it "should have correct failure message for should" do
|
29
|
+
accept_values_for_object.matches?(person)
|
30
|
+
accept_values_for_object.failure_message_for_should.should == "expected #{person.inspect} to accept values \"INVALID\", \"WRONG\" for :gender, but it was not\n\nValue: INVALID\tErrors: gender is not included in the list\nValue: WRONG\tErrors: gender is not included in the list"
|
31
|
+
end
|
18
32
|
end
|
33
|
+
context "when one value is accept and other is not" do
|
34
|
+
let(:values) { ['MALE', 'INVALID'] }
|
35
|
+
it { should be_false }
|
36
|
+
end
|
37
|
+
end
|
19
38
|
|
20
|
-
|
21
|
-
|
22
|
-
|
39
|
+
describe "#does_not_match?" do
|
40
|
+
subject { accept_values_for_object.does_not_match?(person) }
|
41
|
+
context "when value is not accepted" do
|
42
|
+
let(:values) { ['INVALID'] }
|
43
|
+
it { should be_true }
|
44
|
+
end
|
45
|
+
context "when value is accepted" do
|
46
|
+
let(:values) { ['FEMALE'] }
|
47
|
+
it { should be_false }
|
48
|
+
it "should have correct failure message for should" do
|
49
|
+
accept_values_for_object.does_not_match?(person)
|
50
|
+
accept_values_for_object.failure_message_for_should_not.should == "expected #{person.inspect} to not accept values \"FEMALE\" for :gender attribute, but was"
|
51
|
+
end
|
52
|
+
it "should assign the old value for attribute" do
|
53
|
+
accept_values_for_object.does_not_match?(person)
|
54
|
+
person.gender.should == 'MALE'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
context "when 2 values are accepted" do
|
58
|
+
let(:values) { ["FEMALE", "MALE"] }
|
59
|
+
it { should be_false }
|
60
|
+
it "should have correct failure message for should" do
|
61
|
+
accept_values_for_object.does_not_match?(person)
|
62
|
+
accept_values_for_object.failure_message_for_should_not.should == "expected #{person.inspect} to not accept values \"FEMALE\", \"MALE\" for :gender attribute, but was"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
context "when one value is accept and other is not" do
|
66
|
+
let(:values) { ['MALE', 'INVALID'] }
|
67
|
+
it { should be_false }
|
23
68
|
end
|
24
69
|
end
|
25
70
|
|
26
71
|
describe "api" do
|
72
|
+
subject { person }
|
27
73
|
it { should accept_values_for(:gender, "MALE", "FEMALE")}
|
28
74
|
it { should_not accept_values_for(:gender, "INVALID", nil)}
|
29
75
|
it { should_not accept_values_for(:group, nil) }
|
data/spec/discover_spec.rb
CHANGED
@@ -12,41 +12,6 @@ describe "Discover" do
|
|
12
12
|
let(:ruby) { Group.create!(:name => "ruby")}
|
13
13
|
let(:python) { Group.create!(:name => "python")}
|
14
14
|
|
15
|
-
describe "#does_not_match?" do
|
16
|
-
|
17
|
-
context "if scope contains any of the specified values" do
|
18
|
-
subject { discover(java, ruby) }
|
19
|
-
before(:each) do
|
20
|
-
subject.does_not_match?(named_scope).should be_false
|
21
|
-
end
|
22
|
-
|
23
|
-
it { subject.failure_message_for_should_not.should == "expected #{named_scope.inspect} to not include objects: #{[java.id].inspect}, but it was. Found objects: #{named_scope.map(&:id).inspect}"}
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
describe "#matches?" do
|
30
|
-
context "if scope doesn't contain any of the specified objects" do
|
31
|
-
subject { discover(java, ruby) }
|
32
|
-
before(:each) do
|
33
|
-
subject.matches?(named_scope).should be_false
|
34
|
-
end
|
35
|
-
|
36
|
-
it {subject.failure_message_for_should.should == "expected #{named_scope.inspect} to include objects: #{[ruby.id].inspect}, but it was not. Found objects: #{named_scope.map(&:id).inspect}"}
|
37
|
-
end
|
38
|
-
|
39
|
-
context "if scope contain all of the specified objects but without correct order" do
|
40
|
-
subject { discover(jruby, java).with_exact_order }
|
41
|
-
before(:each) do
|
42
|
-
subject.matches?(named_scope).should be_false
|
43
|
-
end
|
44
|
-
|
45
|
-
it "should render error message correctly" do
|
46
|
-
subject.failure_message_for_should.should == "expected #{named_scope.inspect} to be ordered as: #{[jruby.id, java.id].inspect}, but it was not. "
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
15
|
|
51
16
|
describe "api" do
|
52
17
|
subject {
|
@@ -57,8 +22,6 @@ describe "Discover" do
|
|
57
22
|
|
58
23
|
it { should discover(json, java, jruby) }
|
59
24
|
|
60
|
-
it { should discover(java, jruby, json).with_exact_order}
|
61
|
-
it { should discover(java, json).with_exact_order }
|
62
25
|
|
63
26
|
|
64
27
|
it { should_not discover(ruby) }
|
data/spec/spec_helper.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
+
ENV["RAILS_ENV"] ||= 'test'
|
1
2
|
require 'sqlite3'
|
2
3
|
require 'rspec'
|
3
4
|
require 'rspec/autorun'
|
4
|
-
require 'active_record'
|
5
|
+
require 'active_record/railtie'
|
6
|
+
|
7
|
+
$LOAD_PATH << "."
|
5
8
|
require 'lib/accept_values_for'
|
6
9
|
require 'lib/discover'
|
7
10
|
|
8
|
-
require
|
9
|
-
require "rspec/rails/fixture_support"
|
11
|
+
require 'rspec/rails'
|
10
12
|
|
11
13
|
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
12
14
|
ActiveRecord::Base.configurations = true
|
@@ -29,16 +31,13 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
29
31
|
end
|
30
32
|
|
31
33
|
RSpec.configure do |config|
|
32
|
-
config.
|
34
|
+
config.use_transactional_fixtures = true
|
33
35
|
config.before(:each) do
|
34
36
|
class ::Group < ActiveRecord::Base
|
35
37
|
has_many :people
|
36
38
|
|
37
39
|
scope :by_char, lambda { |char|
|
38
|
-
|
39
|
-
:conditions => ["name like ?", char + "%"],
|
40
|
-
:order => "name"
|
41
|
-
}
|
40
|
+
where('name like ?', char + '%').order('name')
|
42
41
|
}
|
43
42
|
end
|
44
43
|
|
metadata
CHANGED
@@ -1,131 +1,133 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: accept_values_for
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 4
|
9
|
-
- 3
|
10
|
-
version: 0.4.3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.1
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Bogdan Gusiev
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2013-10-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
22
15
|
name: activemodel
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.2.0
|
23
22
|
type: :runtime
|
24
23
|
prerelease: false
|
25
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
25
|
none: false
|
27
|
-
requirements:
|
28
|
-
- -
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
|
31
|
-
|
32
|
-
- 3
|
33
|
-
- 0
|
34
|
-
- 0
|
35
|
-
version: 3.0.0
|
36
|
-
requirement: *id001
|
37
|
-
- !ruby/object:Gem::Dependency
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.2.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
38
31
|
name: rspec
|
39
|
-
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
40
39
|
prerelease: false
|
41
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
41
|
none: false
|
43
|
-
requirements:
|
44
|
-
- -
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rails
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 3.2.0
|
53
54
|
type: :development
|
54
55
|
prerelease: false
|
55
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
56
57
|
none: false
|
57
|
-
requirements:
|
58
|
-
- -
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
|
61
|
-
|
62
|
-
- 3
|
63
|
-
- 0
|
64
|
-
- 0
|
65
|
-
version: 3.0.0
|
66
|
-
requirement: *id003
|
67
|
-
- !ruby/object:Gem::Dependency
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.2.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
68
63
|
name: rspec-rails
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 2.0.0
|
69
70
|
type: :development
|
70
71
|
prerelease: false
|
71
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
72
73
|
none: false
|
73
|
-
requirements:
|
74
|
-
- -
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
hash: 15
|
77
|
-
segments:
|
78
|
-
- 2
|
79
|
-
- 0
|
80
|
-
- 0
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
81
77
|
version: 2.0.0
|
82
|
-
|
83
|
-
- !ruby/object:Gem::Dependency
|
78
|
+
- !ruby/object:Gem::Dependency
|
84
79
|
name: jeweler
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
85
86
|
type: :development
|
86
87
|
prerelease: false
|
87
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
88
89
|
none: false
|
89
|
-
requirements:
|
90
|
-
- -
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
|
93
|
-
|
94
|
-
- 0
|
95
|
-
version: "0"
|
96
|
-
requirement: *id005
|
97
|
-
- !ruby/object:Gem::Dependency
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
98
95
|
name: sqlite3-ruby
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
99
102
|
type: :development
|
100
103
|
prerelease: false
|
101
|
-
version_requirements:
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
102
105
|
none: false
|
103
|
-
requirements:
|
104
|
-
- -
|
105
|
-
- !ruby/object:Gem::Version
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
you have to write annoying easy specs on which values should be accepted by your validation method and which should not.
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
description: ! 'Rspec: When you have a complex validation(e.g. regexp or custom method)
|
111
|
+
on ActiveRecord model
|
112
|
+
|
113
|
+
you have to write annoying easy specs on which values should be accepted by your
|
114
|
+
validation method and which should not.
|
115
|
+
|
114
116
|
accepts_values_for rspec matcher simplify the code. See example for more information.
|
115
117
|
|
118
|
+
'
|
116
119
|
email: agresso@gmail.com
|
117
120
|
executables: []
|
118
|
-
|
119
121
|
extensions: []
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
122
|
+
extra_rdoc_files:
|
123
|
+
- LICENSE
|
124
|
+
files:
|
125
|
+
- .travis.yml
|
124
126
|
- Changelog.textile
|
125
127
|
- Gemfile
|
126
|
-
-
|
128
|
+
- LICENSE
|
127
129
|
- Rakefile
|
128
|
-
- Readme.
|
130
|
+
- Readme.md
|
129
131
|
- VERSION
|
130
132
|
- accept_values_for.gemspec
|
131
133
|
- lib/accept_values_for.rb
|
@@ -133,41 +135,32 @@ files:
|
|
133
135
|
- spec/accept_values_for_spec.rb
|
134
136
|
- spec/discover_spec.rb
|
135
137
|
- spec/spec_helper.rb
|
136
|
-
has_rdoc: true
|
137
138
|
homepage: http://github.com/bogdan/accept_values_for
|
138
139
|
licenses: []
|
139
|
-
|
140
140
|
post_install_message:
|
141
141
|
rdoc_options: []
|
142
|
-
|
143
|
-
require_paths:
|
142
|
+
require_paths:
|
144
143
|
- lib
|
145
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
144
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
146
145
|
none: false
|
147
|
-
requirements:
|
148
|
-
- -
|
149
|
-
- !ruby/object:Gem::Version
|
150
|
-
|
151
|
-
segments:
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
segments:
|
152
151
|
- 0
|
153
|
-
|
154
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
|
+
hash: 2380830959568046608
|
153
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
155
154
|
none: false
|
156
|
-
requirements:
|
157
|
-
- -
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
|
160
|
-
segments:
|
161
|
-
- 0
|
162
|
-
version: "0"
|
155
|
+
requirements:
|
156
|
+
- - ! '>='
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
163
159
|
requirements: []
|
164
|
-
|
165
160
|
rubyforge_project:
|
166
|
-
rubygems_version: 1.
|
161
|
+
rubygems_version: 1.8.24
|
167
162
|
signing_key:
|
168
163
|
specification_version: 3
|
169
|
-
summary: In order to test a complex validation for ActiveRecord models Implemented
|
170
|
-
|
171
|
-
|
172
|
-
- spec/discover_spec.rb
|
173
|
-
- spec/spec_helper.rb
|
164
|
+
summary: In order to test a complex validation for ActiveRecord models Implemented
|
165
|
+
accept_values_for custom rspec matcher
|
166
|
+
test_files: []
|
data/Gemfile.lock
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
GEM
|
2
|
-
remote: http://rubygems.org/
|
3
|
-
specs:
|
4
|
-
abstract (1.0.0)
|
5
|
-
actionpack (3.0.3)
|
6
|
-
activemodel (= 3.0.3)
|
7
|
-
activesupport (= 3.0.3)
|
8
|
-
builder (~> 2.1.2)
|
9
|
-
erubis (~> 2.6.6)
|
10
|
-
i18n (~> 0.4)
|
11
|
-
rack (~> 1.2.1)
|
12
|
-
rack-mount (~> 0.6.13)
|
13
|
-
rack-test (~> 0.5.6)
|
14
|
-
tzinfo (~> 0.3.23)
|
15
|
-
activemodel (3.0.3)
|
16
|
-
activesupport (= 3.0.3)
|
17
|
-
builder (~> 2.1.2)
|
18
|
-
i18n (~> 0.4)
|
19
|
-
activerecord (3.0.3)
|
20
|
-
activemodel (= 3.0.3)
|
21
|
-
activesupport (= 3.0.3)
|
22
|
-
arel (~> 2.0.2)
|
23
|
-
tzinfo (~> 0.3.23)
|
24
|
-
activesupport (3.0.3)
|
25
|
-
arel (2.0.7)
|
26
|
-
builder (2.1.2)
|
27
|
-
diff-lcs (1.1.2)
|
28
|
-
erubis (2.6.6)
|
29
|
-
abstract (>= 1.0.0)
|
30
|
-
git (1.2.5)
|
31
|
-
i18n (0.5.0)
|
32
|
-
jeweler (1.5.2)
|
33
|
-
bundler (~> 1.0.0)
|
34
|
-
git (>= 1.2.5)
|
35
|
-
rake
|
36
|
-
rack (1.2.1)
|
37
|
-
rack-mount (0.6.13)
|
38
|
-
rack (>= 1.0.0)
|
39
|
-
rack-test (0.5.7)
|
40
|
-
rack (>= 1.0)
|
41
|
-
railties (3.0.3)
|
42
|
-
actionpack (= 3.0.3)
|
43
|
-
activesupport (= 3.0.3)
|
44
|
-
rake (>= 0.8.7)
|
45
|
-
thor (~> 0.14.4)
|
46
|
-
rake (0.8.7)
|
47
|
-
rspec (2.4.0)
|
48
|
-
rspec-core (~> 2.4.0)
|
49
|
-
rspec-expectations (~> 2.4.0)
|
50
|
-
rspec-mocks (~> 2.4.0)
|
51
|
-
rspec-core (2.4.0)
|
52
|
-
rspec-expectations (2.4.0)
|
53
|
-
diff-lcs (~> 1.1.2)
|
54
|
-
rspec-mocks (2.4.0)
|
55
|
-
rspec-rails (2.4.1)
|
56
|
-
actionpack (~> 3.0)
|
57
|
-
activesupport (~> 3.0)
|
58
|
-
railties (~> 3.0)
|
59
|
-
rspec (~> 2.4.0)
|
60
|
-
sqlite3 (1.3.3)
|
61
|
-
sqlite3-ruby (1.3.3)
|
62
|
-
sqlite3 (>= 1.3.3)
|
63
|
-
thor (0.14.6)
|
64
|
-
tzinfo (0.3.24)
|
65
|
-
|
66
|
-
PLATFORMS
|
67
|
-
ruby
|
68
|
-
|
69
|
-
DEPENDENCIES
|
70
|
-
activemodel (>= 3.0.0)
|
71
|
-
activerecord (>= 3.0.0)
|
72
|
-
jeweler
|
73
|
-
rspec
|
74
|
-
rspec-rails (>= 2.0.0)
|
75
|
-
sqlite3-ruby
|
data/Readme.textile
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
h1. Accept values for
|
2
|
-
|
3
|
-
h2. Description
|
4
|
-
|
5
|
-
In order to spec ActiveRecord models.
|
6
|
-
I decided to write a few custom matchers that makes the work match easier:
|
7
|
-
|
8
|
-
|
9
|
-
h2. Matchers
|
10
|
-
|
11
|
-
* accept_values_for
|
12
|
-
* discover
|
13
|
-
|
14
|
-
h3. Accept values for
|
15
|
-
|
16
|
-
"Rpec matcher to test the validation":http://gusiev.com/2010/06/ultimate-rspec-matcher-to-test-validation/
|
17
|
-
|
18
|
-
<pre>
|
19
|
-
describe User do
|
20
|
-
|
21
|
-
subject { User.new(@valid_attributes)}
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
it { should accept_values_for(:email, "john@example.com", "lambda@gusiev.com") }
|
26
|
-
it { should_not accept_values_for(:email, "invalid", nil, "a@b", "john@.com") }
|
27
|
-
|
28
|
-
end</pre>
|
29
|
-
|
30
|
-
h3. Discovery matcher
|
31
|
-
|
32
|
-
"Rspec matcher to test named scopes":http://gusiev.com/2010/07/bdd-rspec-matcher-to-test-named_scope-scoped-rails
|
33
|
-
|
34
|
-
|
35
|
-
<pre><code>describe "#by_category_id named scope" do
|
36
|
-
let(:given_category) do
|
37
|
-
Factory.create(:given_category)
|
38
|
-
end
|
39
|
-
|
40
|
-
|
41
|
-
let(:product_in_given_category) do
|
42
|
-
Factory.create(
|
43
|
-
:product,
|
44
|
-
:categories => [category]
|
45
|
-
)
|
46
|
-
end
|
47
|
-
|
48
|
-
let(:product_not_in_given_category) do
|
49
|
-
Factory.create(
|
50
|
-
:product,
|
51
|
-
:categories => [Factory.create(:category)]
|
52
|
-
)
|
53
|
-
end
|
54
|
-
|
55
|
-
# This might be tricky to redefine subject as the finder result
|
56
|
-
# but in this way we can delegate the matcher to subject and
|
57
|
-
# avoid writing test descriptions.
|
58
|
-
subject { described_class.by_category_id(given_category.id) }
|
59
|
-
|
60
|
-
it { should discover(product_in_given_category) }
|
61
|
-
it { should_not discover(product_not_in_given_category) }
|
62
|
-
|
63
|
-
end
|
64
|
-
</code></pre>
|
65
|
-
|
66
|
-
|
67
|
-
h2. Dependencies
|
68
|
-
|
69
|
-
* ActiveRecord
|
70
|
-
* Rspec
|
71
|
-
|
72
|
-
h2. Install
|
73
|
-
|
74
|
-
|
75
|
-
h3. Command line:
|
76
|
-
|
77
|
-
<pre>[sudo] gem install accept_values_for</pre>
|
78
|
-
|
79
|
-
h3. spec_helper.rb:
|
80
|
-
|
81
|
-
<pre>require 'accept_values_for'
|
82
|
-
require 'discover'</pre>
|