JonathanTron-rspec_sequel_matchers 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.
- data/VERSION +1 -1
- data/lib/rspec_sequel/association.rb +30 -0
- data/lib/rspec_sequel/base.rb +2 -1
- data/lib/rspec_sequel/matchers/have_column.rb +1 -1
- data/lib/rspec_sequel/matchers/have_many_to_many.rb +22 -0
- data/lib/rspec_sequel/matchers/have_many_to_one.rb +22 -0
- data/lib/rspec_sequel/matchers/have_one_to_many.rb +22 -0
- data/lib/rspec_sequel/matchers/validate_exact_length.rb +25 -0
- data/lib/rspec_sequel/matchers/validate_presence.rb +5 -23
- data/lib/rspec_sequel/validation.rb +73 -0
- data/lib/rspec_sequel_matchers.rb +3 -1
- data/rspec_sequel_matchers.gemspec +20 -2
- data/spec/have_column_matcher_spec.rb +13 -12
- data/spec/have_many_to_many_matcher_spec.rb +55 -0
- data/spec/have_many_to_one_matcher_spec.rb +54 -0
- data/spec/have_one_to_many_matcher_spec.rb +54 -0
- data/spec/migrations/002_create_comments.rb +17 -0
- data/spec/migrations/003_create_comments_items.rb +15 -0
- data/spec/spec_helper.rb +26 -7
- data/spec/validate_exact_length_matcher_spec.rb +86 -0
- data/spec/validate_presence_matcher_spec.rb +34 -13
- metadata +20 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module RspecSequel
|
2
|
+
|
3
|
+
class Association < Base
|
4
|
+
|
5
|
+
def description
|
6
|
+
desc = "have a #{association_type} association #{@attribute.inspect}"
|
7
|
+
desc << " with #{hash_to_nice_string @options}" unless @options.empty?
|
8
|
+
desc
|
9
|
+
end
|
10
|
+
|
11
|
+
def valid?(db, i, c, attribute, options)
|
12
|
+
@association = c.association_reflection(attribute) || {}
|
13
|
+
if @association.empty?
|
14
|
+
@suffix << "(no association #{@attribute.inspect} found)"
|
15
|
+
false
|
16
|
+
else
|
17
|
+
matching = @association[:type] == association_type
|
18
|
+
options.each{|key, value|
|
19
|
+
if @association[key]!=value
|
20
|
+
@suffix << "expected #{key.inspect} == #{value.inspect} but found #{@association[key].inspect} instead"
|
21
|
+
matching = false
|
22
|
+
end
|
23
|
+
}
|
24
|
+
matching
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/lib/rspec_sequel/base.rb
CHANGED
@@ -2,6 +2,7 @@ module RspecSequel
|
|
2
2
|
|
3
3
|
class Base
|
4
4
|
def initialize(attribute, options={})
|
5
|
+
raise ArgumentError, "not enough params for matcher, required attribute is missing" if attribute.nil?
|
5
6
|
@attribute = attribute.to_sym
|
6
7
|
@options = options
|
7
8
|
@description = []
|
@@ -25,7 +26,7 @@ module RspecSequel
|
|
25
26
|
[@prefix, "not", description, @suffix].flatten.compact.join(" ")
|
26
27
|
end
|
27
28
|
def hash_to_nice_string(hash)
|
28
|
-
hash.sort.collect{|param| param.join(" => ")}.join(", ")
|
29
|
+
hash.sort{|a,b| a[0].to_s<=>b[0].to_s}.collect{|param| param.collect{|v| v.inspect}.join(" => ")}.join(", ")
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module RspecSequel
|
2
|
+
module Matchers
|
3
|
+
|
4
|
+
class HaveManyToManyMatcher < RspecSequel::Association
|
5
|
+
def association_type
|
6
|
+
:many_to_many
|
7
|
+
end
|
8
|
+
|
9
|
+
def valid?(db, i, c, attribute, options)
|
10
|
+
matching = super
|
11
|
+
|
12
|
+
# check that association model exists, etc.
|
13
|
+
matching
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def have_many_to_many(*args)
|
18
|
+
HaveManyToManyMatcher.new(*args)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module RspecSequel
|
2
|
+
module Matchers
|
3
|
+
|
4
|
+
class HaveManyToOneMatcher < RspecSequel::Association
|
5
|
+
def association_type
|
6
|
+
:many_to_one
|
7
|
+
end
|
8
|
+
|
9
|
+
def valid?(db, i, c, attribute, options)
|
10
|
+
matching = super
|
11
|
+
|
12
|
+
# check that association model exists, etc.
|
13
|
+
matching
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def have_many_to_one(*args)
|
18
|
+
HaveManyToOneMatcher.new(*args)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module RspecSequel
|
2
|
+
module Matchers
|
3
|
+
|
4
|
+
class HaveOneToManyMatcher < RspecSequel::Association
|
5
|
+
def association_type
|
6
|
+
:one_to_many
|
7
|
+
end
|
8
|
+
|
9
|
+
def valid?(db, i, c, attribute, options)
|
10
|
+
matching = super
|
11
|
+
|
12
|
+
# check that association model exists, etc.
|
13
|
+
matching
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def have_one_to_many(*args)
|
18
|
+
HaveOneToManyMatcher.new(*args)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RspecSequel
|
2
|
+
module Matchers
|
3
|
+
|
4
|
+
class ValidateExactLengthMatcher < RspecSequel::Validation
|
5
|
+
def description
|
6
|
+
desc = "validate exact length of #{@attribute.inspect} to #{@additionnal.inspect}"
|
7
|
+
desc << " with #{hash_to_nice_string @options}" unless @options.empty?
|
8
|
+
desc
|
9
|
+
end
|
10
|
+
|
11
|
+
def additionnal_param_type
|
12
|
+
Fixnum
|
13
|
+
end
|
14
|
+
|
15
|
+
def validation_type
|
16
|
+
:validates_exact_length
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def validate_exact_length(*args)
|
21
|
+
ValidateExactLengthMatcher.new(*args)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -1,33 +1,15 @@
|
|
1
1
|
module RspecSequel
|
2
2
|
module Matchers
|
3
3
|
|
4
|
-
class ValidatePresenceMatcher < RspecSequel::
|
4
|
+
class ValidatePresenceMatcher < RspecSequel::Validation
|
5
5
|
def description
|
6
|
-
desc = "validate presence of
|
7
|
-
unless @options.empty?
|
8
|
-
desc << " with #{hash_to_nice_string @options}"
|
9
|
-
end
|
6
|
+
desc = "validate presence of #{@attribute.inspect}"
|
7
|
+
desc << " with #{hash_to_nice_string @options}" unless @options.empty?
|
10
8
|
desc
|
11
9
|
end
|
12
10
|
|
13
|
-
def
|
14
|
-
|
15
|
-
# check column existance
|
16
|
-
called_count = 0
|
17
|
-
i = i.dup
|
18
|
-
i.stub!(:validates_presence).and_return{|*args|
|
19
|
-
if args.shift==attribute
|
20
|
-
if options.empty?
|
21
|
-
called_count += 1
|
22
|
-
else
|
23
|
-
called_options = args.shift
|
24
|
-
@suffix << "(called with #{hash_to_nice_string called_options})"
|
25
|
-
called_count +=1 if called_options==options
|
26
|
-
end
|
27
|
-
end
|
28
|
-
}
|
29
|
-
i.valid?
|
30
|
-
called_count==1
|
11
|
+
def validation_type
|
12
|
+
:validates_presence
|
31
13
|
end
|
32
14
|
end
|
33
15
|
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module RspecSequel
|
2
|
+
|
3
|
+
class Validation < Base
|
4
|
+
|
5
|
+
def initialize(*args)
|
6
|
+
# initialize Base
|
7
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
8
|
+
super(args.pop, options)
|
9
|
+
|
10
|
+
# check additionnal param
|
11
|
+
if additionnal_param_required?
|
12
|
+
if args.size>1
|
13
|
+
raise ArgumentError, "too many params for matcher"
|
14
|
+
else
|
15
|
+
@additionnal = args.pop
|
16
|
+
raise ArgumentError, "expected matcher first parameter to be #{additionnal_param_type.inspect} but received #{@additionnal.class.inspect} instead" unless @additionnal.kind_of?(additionnal_param_type)
|
17
|
+
end
|
18
|
+
else
|
19
|
+
raise ArgumentError, "too many params for matcher" unless args.empty?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def additionnal_param_type
|
24
|
+
NilClass
|
25
|
+
end
|
26
|
+
|
27
|
+
def additionnal_param_required?
|
28
|
+
additionnal_param_type!=NilClass
|
29
|
+
end
|
30
|
+
|
31
|
+
def valid_options
|
32
|
+
[:allow_blank, :allow_missing, :allow_nil, :message]
|
33
|
+
end
|
34
|
+
|
35
|
+
def valid?(db, i, c, attribute, options)
|
36
|
+
# check options
|
37
|
+
invalid_options = options.keys.reject{|o| valid_options.include?(o)}
|
38
|
+
invalid_options.each{|o|
|
39
|
+
@suffix << "but option #{o.inspect} is not valid"
|
40
|
+
}
|
41
|
+
return false unless invalid_options.empty?
|
42
|
+
|
43
|
+
# check validation itself
|
44
|
+
called_count = 0
|
45
|
+
i = i.dup
|
46
|
+
i.class.columns # ensure colums are read again after .dup
|
47
|
+
i.stub!(validation_type).and_return{|*args|
|
48
|
+
called_options = args.last.is_a?(Hash) ? args.pop : {}
|
49
|
+
called_attributes = [args.pop].flatten
|
50
|
+
called_additionnal = args.shift if additionnal_param_required?
|
51
|
+
if !args.empty?
|
52
|
+
@suffix << "but called with too many params"
|
53
|
+
elsif called_attributes.include?(attribute)
|
54
|
+
if additionnal_param_required? && @additionnal!=called_additionnal
|
55
|
+
@suffix << "but called with #{called_additionnal} instead"
|
56
|
+
elsif !options.empty? && called_options!=options
|
57
|
+
@suffix << "but called with option(s) #{hash_to_nice_string called_options} instead"
|
58
|
+
else
|
59
|
+
called_count += 1
|
60
|
+
end
|
61
|
+
end
|
62
|
+
}
|
63
|
+
i.valid?
|
64
|
+
if called_count>1
|
65
|
+
@suffix << "but validation is called too many times"
|
66
|
+
return false
|
67
|
+
end
|
68
|
+
called_count==1
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# Load base
|
2
|
-
|
2
|
+
["base", "association", "validation"].each do |file|
|
3
|
+
require File.join(File.dirname(__FILE__), "rspec_sequel", file)
|
4
|
+
end
|
3
5
|
|
4
6
|
# Add matchers
|
5
7
|
Dir[File.join(File.dirname(__FILE__), "rspec_sequel", "matchers", "*.rb")].each do |file|
|
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{rspec_sequel_matchers}
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.2"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Jonathan Tron", "Joseph Halter"]
|
9
|
-
s.date = %q{2009-08-
|
9
|
+
s.date = %q{2009-08-13}
|
10
10
|
s.email = %q{jonathan@tron.name}
|
11
11
|
s.extra_rdoc_files = [
|
12
12
|
"LICENSE",
|
@@ -19,14 +19,26 @@ Gem::Specification.new do |s|
|
|
19
19
|
"README.rdoc",
|
20
20
|
"Rakefile",
|
21
21
|
"VERSION",
|
22
|
+
"lib/rspec_sequel/association.rb",
|
22
23
|
"lib/rspec_sequel/base.rb",
|
23
24
|
"lib/rspec_sequel/matchers/have_column.rb",
|
25
|
+
"lib/rspec_sequel/matchers/have_many_to_many.rb",
|
26
|
+
"lib/rspec_sequel/matchers/have_many_to_one.rb",
|
27
|
+
"lib/rspec_sequel/matchers/have_one_to_many.rb",
|
28
|
+
"lib/rspec_sequel/matchers/validate_exact_length.rb",
|
24
29
|
"lib/rspec_sequel/matchers/validate_presence.rb",
|
30
|
+
"lib/rspec_sequel/validation.rb",
|
25
31
|
"lib/rspec_sequel_matchers.rb",
|
26
32
|
"rspec_sequel_matchers.gemspec",
|
27
33
|
"spec/have_column_matcher_spec.rb",
|
34
|
+
"spec/have_many_to_many_matcher_spec.rb",
|
35
|
+
"spec/have_many_to_one_matcher_spec.rb",
|
36
|
+
"spec/have_one_to_many_matcher_spec.rb",
|
28
37
|
"spec/migrations/001_create_items.rb",
|
38
|
+
"spec/migrations/002_create_comments.rb",
|
39
|
+
"spec/migrations/003_create_comments_items.rb",
|
29
40
|
"spec/spec_helper.rb",
|
41
|
+
"spec/validate_exact_length_matcher_spec.rb",
|
30
42
|
"spec/validate_presence_matcher_spec.rb"
|
31
43
|
]
|
32
44
|
s.has_rdoc = true
|
@@ -37,8 +49,14 @@ Gem::Specification.new do |s|
|
|
37
49
|
s.summary = %q{TODO}
|
38
50
|
s.test_files = [
|
39
51
|
"spec/have_column_matcher_spec.rb",
|
52
|
+
"spec/have_many_to_many_matcher_spec.rb",
|
53
|
+
"spec/have_many_to_one_matcher_spec.rb",
|
54
|
+
"spec/have_one_to_many_matcher_spec.rb",
|
40
55
|
"spec/migrations/001_create_items.rb",
|
56
|
+
"spec/migrations/002_create_comments.rb",
|
57
|
+
"spec/migrations/003_create_comments_items.rb",
|
41
58
|
"spec/spec_helper.rb",
|
59
|
+
"spec/validate_exact_length_matcher_spec.rb",
|
42
60
|
"spec/validate_presence_matcher_spec.rb"
|
43
61
|
]
|
44
62
|
|
@@ -1,10 +1,11 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/spec_helper"
|
2
2
|
|
3
|
-
class Item < Sequel::Model
|
4
|
-
end
|
5
|
-
|
6
3
|
describe "have_column_matcher" do
|
7
4
|
|
5
|
+
before :all do
|
6
|
+
define_model :item
|
7
|
+
end
|
8
|
+
|
8
9
|
subject{ Item }
|
9
10
|
|
10
11
|
describe "messages" do
|
@@ -17,7 +18,7 @@ describe "have_column_matcher" do
|
|
17
18
|
@matcher = have_column :name
|
18
19
|
@matcher.matches? subject
|
19
20
|
@matcher.failure_message.should == "expected Item to have a column :name"
|
20
|
-
@matcher.negative_failure_message.should == "
|
21
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to have", "to not have")
|
21
22
|
end
|
22
23
|
end
|
23
24
|
describe "with type as symbol" do
|
@@ -29,7 +30,7 @@ describe "have_column_matcher" do
|
|
29
30
|
@matcher = have_column :password, :type => :string
|
30
31
|
@matcher.matches? subject
|
31
32
|
@matcher.failure_message.should == "expected Item to have a column :password with type string"
|
32
|
-
@matcher.negative_failure_message.should == "
|
33
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to have", "to not have")
|
33
34
|
end
|
34
35
|
end
|
35
36
|
describe "with type as object" do
|
@@ -41,21 +42,21 @@ describe "have_column_matcher" do
|
|
41
42
|
@matcher = have_column :password, :type => String
|
42
43
|
@matcher.matches? subject
|
43
44
|
@matcher.failure_message.should == "expected Item to have a column :password with type String"
|
44
|
-
@matcher.negative_failure_message.should == "
|
45
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to have", "to not have")
|
45
46
|
end
|
46
47
|
it "should explicit found type if different than expected" do
|
47
48
|
@matcher = have_column :name, :type => Integer
|
48
49
|
@matcher.matches? subject
|
49
50
|
@matcher.failure_message.should == "expected Item to have a column :name with type Integer (type found: string, varchar(255))"
|
50
|
-
@matcher.negative_failure_message.should == "
|
51
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to have", "to not have")
|
51
52
|
end
|
52
53
|
end
|
53
54
|
describe "on anonymous Sequel::Model class" do
|
54
55
|
it "should set failure messages" do
|
55
56
|
@matcher = have_column :password
|
56
|
-
@matcher.matches? Sequel::Model(:
|
57
|
-
@matcher.failure_message.should == "expected
|
58
|
-
@matcher.negative_failure_message.should == "
|
57
|
+
@matcher.matches? Sequel::Model(:comments)
|
58
|
+
@matcher.failure_message.should == "expected comments to have a column :password"
|
59
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to have", "to not have")
|
59
60
|
end
|
60
61
|
end
|
61
62
|
describe "on Sequel::Model class" do
|
@@ -63,7 +64,7 @@ describe "have_column_matcher" do
|
|
63
64
|
@matcher = have_column :password
|
64
65
|
@matcher.matches? Item
|
65
66
|
@matcher.failure_message.should == "expected Item to have a column :password"
|
66
|
-
@matcher.negative_failure_message.should == "
|
67
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to have", "to not have")
|
67
68
|
end
|
68
69
|
end
|
69
70
|
describe "on Sequel::Model instance" do
|
@@ -71,7 +72,7 @@ describe "have_column_matcher" do
|
|
71
72
|
@matcher = have_column :password
|
72
73
|
@matcher.matches? Item.new
|
73
74
|
@matcher.failure_message.should == "expected #<Item @values={}> to have a column :password"
|
74
|
-
@matcher.negative_failure_message.should == "
|
75
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to have", "to not have")
|
75
76
|
end
|
76
77
|
end
|
77
78
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper"
|
2
|
+
|
3
|
+
describe "have_many_to_many_matcher" do
|
4
|
+
|
5
|
+
before :all do
|
6
|
+
define_model :item
|
7
|
+
define_model :comment do
|
8
|
+
many_to_many :items
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
subject{ Comment }
|
13
|
+
|
14
|
+
describe "messages" do
|
15
|
+
describe "without option" do
|
16
|
+
it "should contain a description" do
|
17
|
+
@matcher = have_many_to_many :items
|
18
|
+
@matcher.description.should == "have a many_to_many association :items"
|
19
|
+
end
|
20
|
+
it "should set failure messages" do
|
21
|
+
@matcher = have_many_to_many :items
|
22
|
+
@matcher.matches? subject
|
23
|
+
@matcher.failure_message.should == "expected Comment to have a many_to_many association :items"
|
24
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to have", "to not have")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
describe "with options" do
|
28
|
+
it "should contain a description" do
|
29
|
+
@matcher = have_many_to_many :items, :class_name => "Item"
|
30
|
+
@matcher.description.should == 'have a many_to_many association :items with :class_name => "Item"'
|
31
|
+
end
|
32
|
+
it "should set failure messages" do
|
33
|
+
@matcher = have_many_to_many :items, :class_name => "Item"
|
34
|
+
@matcher.matches? subject
|
35
|
+
@matcher.failure_message.should == 'expected Comment to have a many_to_many association :items with :class_name => "Item"'
|
36
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to have", "to not have")
|
37
|
+
end
|
38
|
+
it "should explicit used options if different than expected" do
|
39
|
+
@matcher = have_many_to_many :items, :class_name => "Price"
|
40
|
+
@matcher.matches? subject
|
41
|
+
@matcher.failure_message.should == 'expected Comment to have a many_to_many association :items with :class_name => "Price" expected :class_name == "Price" but found "Item" instead'
|
42
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to have", "to not have")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "matchers" do
|
48
|
+
it{ should have_many_to_many(:items) }
|
49
|
+
it{ should have_many_to_many(:items, :class_name => "Item", :join_table => :comments_items) }
|
50
|
+
it{ should_not have_many_to_many(:prices) }
|
51
|
+
it{ should_not have_many_to_many(:items, :class_name => "Price") }
|
52
|
+
it{ should_not have_many_to_many(:items, :join_table => :items_comments) }
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper"
|
2
|
+
|
3
|
+
describe "have_many_to_one_matcher" do
|
4
|
+
|
5
|
+
before :all do
|
6
|
+
define_model :item
|
7
|
+
define_model :comment do
|
8
|
+
many_to_one :item
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
subject{ Comment }
|
13
|
+
|
14
|
+
describe "messages" do
|
15
|
+
describe "without option" do
|
16
|
+
it "should contain a description" do
|
17
|
+
@matcher = have_many_to_one :item
|
18
|
+
@matcher.description.should == "have a many_to_one association :item"
|
19
|
+
end
|
20
|
+
it "should set failure messages" do
|
21
|
+
@matcher = have_many_to_one :item
|
22
|
+
@matcher.matches? subject
|
23
|
+
@matcher.failure_message.should == "expected Comment to have a many_to_one association :item"
|
24
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to have", "to not have")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
describe "with options" do
|
28
|
+
it "should contain a description" do
|
29
|
+
@matcher = have_many_to_one :item, :class_name => "Item"
|
30
|
+
@matcher.description.should == 'have a many_to_one association :item with :class_name => "Item"'
|
31
|
+
end
|
32
|
+
it "should set failure messages" do
|
33
|
+
@matcher = have_many_to_one :item, :class_name => "Item"
|
34
|
+
@matcher.matches? subject
|
35
|
+
@matcher.failure_message.should == 'expected Comment to have a many_to_one association :item with :class_name => "Item"'
|
36
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to have", "to not have")
|
37
|
+
end
|
38
|
+
it "should explicit used options if different than expected" do
|
39
|
+
@matcher = have_many_to_one :item, :class_name => "Price"
|
40
|
+
@matcher.matches? subject
|
41
|
+
@matcher.failure_message.should == 'expected Comment to have a many_to_one association :item with :class_name => "Price" expected :class_name == "Price" but found "Item" instead'
|
42
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to have", "to not have")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "matchers" do
|
48
|
+
it{ should have_many_to_one(:item) }
|
49
|
+
it{ should have_many_to_one(:item, :class_name => "Item") }
|
50
|
+
it{ should_not have_many_to_one(:price) }
|
51
|
+
it{ should_not have_many_to_one(:item, :class_name => "Price") }
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper"
|
2
|
+
|
3
|
+
describe "have_one_to_many_matcher" do
|
4
|
+
|
5
|
+
before :all do
|
6
|
+
define_model :item do
|
7
|
+
one_to_many :comments
|
8
|
+
end
|
9
|
+
define_model :comment
|
10
|
+
end
|
11
|
+
|
12
|
+
subject{ Item }
|
13
|
+
|
14
|
+
describe "messages" do
|
15
|
+
describe "without option" do
|
16
|
+
it "should contain a description" do
|
17
|
+
@matcher = have_one_to_many :comments
|
18
|
+
@matcher.description.should == "have a one_to_many association :comments"
|
19
|
+
end
|
20
|
+
it "should set failure messages" do
|
21
|
+
@matcher = have_one_to_many :comments
|
22
|
+
@matcher.matches? subject
|
23
|
+
@matcher.failure_message.should == "expected Item to have a one_to_many association :comments"
|
24
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to have", "to not have")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
describe "with options" do
|
28
|
+
it "should contain a description" do
|
29
|
+
@matcher = have_one_to_many :comments, :class_name => "Comment"
|
30
|
+
@matcher.description.should == 'have a one_to_many association :comments with :class_name => "Comment"'
|
31
|
+
end
|
32
|
+
it "should set failure messages" do
|
33
|
+
@matcher = have_one_to_many :comments, :class_name => "Comment"
|
34
|
+
@matcher.matches? subject
|
35
|
+
@matcher.failure_message.should == 'expected Item to have a one_to_many association :comments with :class_name => "Comment"'
|
36
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to have", "to not have")
|
37
|
+
end
|
38
|
+
it "should explicit used options if different than expected" do
|
39
|
+
@matcher = have_one_to_many :comments, :class_name => "Price"
|
40
|
+
@matcher.matches? subject
|
41
|
+
@matcher.failure_message.should == 'expected Item to have a one_to_many association :comments with :class_name => "Price" expected :class_name == "Price" but found "Comment" instead'
|
42
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to have", "to not have")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "matchers" do
|
48
|
+
it{ should have_one_to_many(:comments) }
|
49
|
+
it{ should have_one_to_many(:comments, :class_name => "Comment") }
|
50
|
+
it{ should_not have_one_to_many(:prices) }
|
51
|
+
it{ should_not have_one_to_many(:comments, :class_name => "Price") }
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateComments < Sequel::Migration
|
2
|
+
|
3
|
+
def up
|
4
|
+
create_table :comments do
|
5
|
+
primary_key :id
|
6
|
+
foreign_key :item_id, :items, :type => Fixnum
|
7
|
+
String :content
|
8
|
+
DateTime :created_at
|
9
|
+
index :item_id
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def down
|
14
|
+
drop_table :comments
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateCommentsItems < Sequel::Migration
|
2
|
+
|
3
|
+
def up
|
4
|
+
create_table :comments_items do
|
5
|
+
foreign_key :comment_id, :comments, :type => Fixnum
|
6
|
+
foreign_key :item_id, :items, :type => Fixnum
|
7
|
+
index [:comment_id, :item_id], :unique => true
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def down
|
12
|
+
drop_table :comments_items
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "spec"
|
2
2
|
require "rubygems"
|
3
3
|
require "sequel"
|
4
|
+
require "sequel/extensions/inflector"
|
4
5
|
require "sequel/extensions/migration"
|
5
6
|
require File.join(File.dirname(__FILE__), "..", "lib", "rspec_sequel_matchers")
|
6
7
|
|
@@ -9,19 +10,37 @@ begin
|
|
9
10
|
Sequel.sqlite
|
10
11
|
rescue Sequel::AdapterNotFound
|
11
12
|
puts "sqlite not available. Install it with: sudo gem install sqlite3-ruby"
|
13
|
+
exit 1 # failure
|
14
|
+
end
|
15
|
+
|
16
|
+
# drop all tables and migrate on start
|
17
|
+
db = Sequel::Model.db
|
18
|
+
db.tables.each do |table_name|
|
19
|
+
db.drop_table table_name
|
20
|
+
end
|
21
|
+
Sequel::Migrator.apply(db, File.join(File.dirname(__FILE__), "migrations"))
|
22
|
+
|
23
|
+
def define_model(model, &block)
|
24
|
+
model_name = model.to_s.camelize.to_sym
|
25
|
+
table_name = model.to_s.tableize.to_sym
|
26
|
+
@defined_models ||= []
|
27
|
+
@defined_models << model_name
|
28
|
+
klass = Object.const_set model_name, Sequel::Model(table_name)
|
29
|
+
klass.class_eval &block if block_given?
|
12
30
|
end
|
13
31
|
|
14
32
|
Spec::Runner.configure do |config|
|
15
33
|
config.include(RspecSequel::Matchers)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
34
|
+
|
35
|
+
# undefine models defined via define_model (if any)
|
36
|
+
config.after(:all) do
|
37
|
+
@defined_models.each{|model_name|
|
38
|
+
Object.send(:remove_const, model_name)
|
39
|
+
}
|
40
|
+
@defined_models = nil
|
23
41
|
end
|
24
42
|
|
43
|
+
# truncate all tables between each spec
|
25
44
|
config.after(:each) do
|
26
45
|
db = Sequel::Model.db
|
27
46
|
db.tables.each do |table_name|
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper"
|
2
|
+
|
3
|
+
describe "validate_exact_length_matcher" do
|
4
|
+
|
5
|
+
before :all do
|
6
|
+
define_model :item do
|
7
|
+
plugin :validation_helpers
|
8
|
+
def validate
|
9
|
+
validates_exact_length 4, :name, :allow_nil => true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
subject{ Item }
|
15
|
+
|
16
|
+
describe "arguments" do
|
17
|
+
it "should require attribute" do
|
18
|
+
lambda{
|
19
|
+
@matcher = validate_exact_length
|
20
|
+
}.should raise_error(ArgumentError)
|
21
|
+
end
|
22
|
+
it "should require additionnal parameters" do
|
23
|
+
lambda{
|
24
|
+
@matcher = validate_exact_length :name
|
25
|
+
}.should raise_error(ArgumentError)
|
26
|
+
end
|
27
|
+
it "should refuse invalid additionnal parameters" do
|
28
|
+
lambda{
|
29
|
+
@matcher = validate_exact_length :id, :name
|
30
|
+
}.should raise_error(ArgumentError)
|
31
|
+
end
|
32
|
+
it "should accept valid additionnal parameters" do
|
33
|
+
lambda{
|
34
|
+
@matcher = validate_exact_length 4, :name
|
35
|
+
}.should_not raise_error(ArgumentError)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "messages" do
|
40
|
+
describe "without option" do
|
41
|
+
it "should contain a description" do
|
42
|
+
@matcher = validate_exact_length 4, :name
|
43
|
+
@matcher.description.should == "validate exact length of :name to 4"
|
44
|
+
end
|
45
|
+
it "should set failure messages" do
|
46
|
+
@matcher = validate_exact_length 4, :name
|
47
|
+
@matcher.matches? subject
|
48
|
+
@matcher.failure_message.should == "expected Item to validate exact length of :name to 4"
|
49
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to validate", "to not validate")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
describe "with options" do
|
53
|
+
it "should contain a description" do
|
54
|
+
@matcher = validate_exact_length 4, :name, :allow_nil => true
|
55
|
+
@matcher.description.should == "validate exact length of :name to 4 with :allow_nil => true"
|
56
|
+
end
|
57
|
+
it "should set failure messages" do
|
58
|
+
@matcher = validate_exact_length 4, :price, :allow_nil => true
|
59
|
+
@matcher.matches? subject
|
60
|
+
@matcher.failure_message.should == "expected Item to validate exact length of :price to 4 with :allow_nil => true"
|
61
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to validate", "to not validate")
|
62
|
+
end
|
63
|
+
it "should explicit used options if different than expected" do
|
64
|
+
@matcher = validate_exact_length 4, :name, :allow_blank => true
|
65
|
+
@matcher.matches? subject
|
66
|
+
@matcher.failure_message.should == "expected Item to validate exact length of :name to 4 with :allow_blank => true but called with option(s) :allow_nil => true instead"
|
67
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to validate", "to not validate")
|
68
|
+
end
|
69
|
+
it "should warn if invalid options are used" do
|
70
|
+
@matcher = validate_exact_length 4, :name, :allow_anything => true
|
71
|
+
@matcher.matches? subject
|
72
|
+
@matcher.failure_message.should == "expected Item to validate exact length of :name to 4 with :allow_anything => true but option :allow_anything is not valid"
|
73
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to validate", "to not validate")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "matchers" do
|
79
|
+
it{ should validate_exact_length(4, :name) }
|
80
|
+
it{ should validate_exact_length(4, :name, :allow_nil => true) }
|
81
|
+
it{ should_not validate_exact_length(4, :price) }
|
82
|
+
it{ should_not validate_exact_length(3, :name) }
|
83
|
+
it{ should_not validate_exact_length(4, :name, :allow_blank => true) }
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -1,16 +1,31 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/spec_helper"
|
2
2
|
|
3
|
-
class Item < Sequel::Model
|
4
|
-
plugin :validation_helpers
|
5
|
-
def validate
|
6
|
-
validates_presence :name, :allow_nil => true
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
3
|
describe "validate_presence_matcher" do
|
11
4
|
|
5
|
+
before :all do
|
6
|
+
define_model :item do
|
7
|
+
plugin :validation_helpers
|
8
|
+
def validate
|
9
|
+
validates_presence [:id, :name], :allow_nil => true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
12
14
|
subject{ Item }
|
13
15
|
|
16
|
+
describe "arguments" do
|
17
|
+
it "should require attribute" do
|
18
|
+
lambda{
|
19
|
+
@matcher = validate_presence
|
20
|
+
}.should raise_error(ArgumentError)
|
21
|
+
end
|
22
|
+
it "should refuse additionnal parameters" do
|
23
|
+
lambda{
|
24
|
+
@matcher = validate_presence :name, :id
|
25
|
+
}.should raise_error(ArgumentError)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
14
29
|
describe "messages" do
|
15
30
|
describe "without option" do
|
16
31
|
it "should contain a description" do
|
@@ -21,25 +36,31 @@ describe "validate_presence_matcher" do
|
|
21
36
|
@matcher = validate_presence :name
|
22
37
|
@matcher.matches? subject
|
23
38
|
@matcher.failure_message.should == "expected Item to validate presence of :name"
|
24
|
-
@matcher.negative_failure_message.should == "
|
39
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to validate", "to not validate")
|
25
40
|
end
|
26
41
|
end
|
27
42
|
describe "with options" do
|
28
43
|
it "should contain a description" do
|
29
44
|
@matcher = validate_presence :name, :allow_nil => true
|
30
|
-
@matcher.description.should == "validate presence of :name with allow_nil => true"
|
45
|
+
@matcher.description.should == "validate presence of :name with :allow_nil => true"
|
31
46
|
end
|
32
47
|
it "should set failure messages" do
|
33
48
|
@matcher = validate_presence :price, :allow_nil => true
|
34
49
|
@matcher.matches? subject
|
35
|
-
@matcher.failure_message.should == "expected Item to validate presence of :price with allow_nil => true"
|
36
|
-
@matcher.negative_failure_message.should == "
|
50
|
+
@matcher.failure_message.should == "expected Item to validate presence of :price with :allow_nil => true"
|
51
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to validate", "to not validate")
|
37
52
|
end
|
38
53
|
it "should explicit used options if different than expected" do
|
39
54
|
@matcher = validate_presence :name, :allow_blank => true
|
40
55
|
@matcher.matches? subject
|
41
|
-
@matcher.failure_message.should == "expected Item to validate presence of :name with allow_blank => true
|
42
|
-
@matcher.negative_failure_message.should == "
|
56
|
+
@matcher.failure_message.should == "expected Item to validate presence of :name with :allow_blank => true but called with option(s) :allow_nil => true instead"
|
57
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to validate", "to not validate")
|
58
|
+
end
|
59
|
+
it "should warn if invalid options are used" do
|
60
|
+
@matcher = validate_presence :name, :allow_anything => true
|
61
|
+
@matcher.matches? subject
|
62
|
+
@matcher.failure_message.should == "expected Item to validate presence of :name with :allow_anything => true but option :allow_anything is not valid"
|
63
|
+
@matcher.negative_failure_message.should == @matcher.failure_message.gsub("to validate", "to not validate")
|
43
64
|
end
|
44
65
|
end
|
45
66
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: JonathanTron-rspec_sequel_matchers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Tron
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-08-
|
13
|
+
date: 2009-08-13 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -49,14 +49,26 @@ files:
|
|
49
49
|
- README.rdoc
|
50
50
|
- Rakefile
|
51
51
|
- VERSION
|
52
|
+
- lib/rspec_sequel/association.rb
|
52
53
|
- lib/rspec_sequel/base.rb
|
53
54
|
- lib/rspec_sequel/matchers/have_column.rb
|
55
|
+
- lib/rspec_sequel/matchers/have_many_to_many.rb
|
56
|
+
- lib/rspec_sequel/matchers/have_many_to_one.rb
|
57
|
+
- lib/rspec_sequel/matchers/have_one_to_many.rb
|
58
|
+
- lib/rspec_sequel/matchers/validate_exact_length.rb
|
54
59
|
- lib/rspec_sequel/matchers/validate_presence.rb
|
60
|
+
- lib/rspec_sequel/validation.rb
|
55
61
|
- lib/rspec_sequel_matchers.rb
|
56
62
|
- rspec_sequel_matchers.gemspec
|
57
63
|
- spec/have_column_matcher_spec.rb
|
64
|
+
- spec/have_many_to_many_matcher_spec.rb
|
65
|
+
- spec/have_many_to_one_matcher_spec.rb
|
66
|
+
- spec/have_one_to_many_matcher_spec.rb
|
58
67
|
- spec/migrations/001_create_items.rb
|
68
|
+
- spec/migrations/002_create_comments.rb
|
69
|
+
- spec/migrations/003_create_comments_items.rb
|
59
70
|
- spec/spec_helper.rb
|
71
|
+
- spec/validate_exact_length_matcher_spec.rb
|
60
72
|
- spec/validate_presence_matcher_spec.rb
|
61
73
|
has_rdoc: true
|
62
74
|
homepage: http://github.com/JonathanTron/rspec_sequel_matchers
|
@@ -87,6 +99,12 @@ specification_version: 2
|
|
87
99
|
summary: TODO
|
88
100
|
test_files:
|
89
101
|
- spec/have_column_matcher_spec.rb
|
102
|
+
- spec/have_many_to_many_matcher_spec.rb
|
103
|
+
- spec/have_many_to_one_matcher_spec.rb
|
104
|
+
- spec/have_one_to_many_matcher_spec.rb
|
90
105
|
- spec/migrations/001_create_items.rb
|
106
|
+
- spec/migrations/002_create_comments.rb
|
107
|
+
- spec/migrations/003_create_comments_items.rb
|
91
108
|
- spec/spec_helper.rb
|
109
|
+
- spec/validate_exact_length_matcher_spec.rb
|
92
110
|
- spec/validate_presence_matcher_spec.rb
|