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 CHANGED
@@ -1 +1 @@
1
- 0.0.1
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
@@ -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
 
@@ -3,7 +3,7 @@ module RspecSequel
3
3
 
4
4
  class HaveColumnMatcher < RspecSequel::Base
5
5
  def description
6
- desc = "have a column :#{@attribute}"
6
+ desc = "have a column #{@attribute.inspect}"
7
7
  desc << " with type #{@options[:type]}" if @options[:type]
8
8
  desc
9
9
  end
@@ -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::Base
4
+ class ValidatePresenceMatcher < RspecSequel::Validation
5
5
  def description
6
- desc = "validate presence of :#{@attribute}"
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 valid?(db, i, c, attribute, options)
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
- require File.join(File.dirname(__FILE__), "rspec_sequel", "base")
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.1"
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-05}
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 == "expected Item to not have a column :name"
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 == "expected Item to not have a column :password with type string"
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 == "expected Item to not have a column :password with type String"
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 == "expected Item to not have a column :name with type Integer (type found: string, varchar(255))"
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(:items)
57
- @matcher.failure_message.should == "expected items to have a column :password"
58
- @matcher.negative_failure_message.should == "expected items to not have a column :password"
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 == "expected Item to not have a column :password"
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 == "expected #<Item @values={}> to not have a column :password"
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
- config.before(:all) do
18
- db = Sequel::Model.db
19
- db.tables.each do |table_name|
20
- db["DROP #{table_name}"]
21
- end
22
- Sequel::Migrator.apply(db, File.join(File.dirname(__FILE__), "migrations"))
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 == "expected Item to not validate presence of :name"
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 == "expected Item to not validate presence of :price with allow_nil => true"
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 (called with allow_nil => true)"
42
- @matcher.negative_failure_message.should == "expected Item to not validate presence of :name with allow_blank => true (called with allow_nil => true)"
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.1
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-05 00:00:00 -07:00
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