openhood-rspec_sequel_matchers 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +47 -0
  3. data/Rakefile +48 -0
  4. data/VERSION.yml +4 -0
  5. data/lib/rspec_sequel/association.rb +30 -0
  6. data/lib/rspec_sequel/base.rb +33 -0
  7. data/lib/rspec_sequel/matchers/have_column.rb +35 -0
  8. data/lib/rspec_sequel/matchers/have_many_to_many.rb +22 -0
  9. data/lib/rspec_sequel/matchers/have_many_to_one.rb +22 -0
  10. data/lib/rspec_sequel/matchers/have_one_to_many.rb +22 -0
  11. data/lib/rspec_sequel/matchers/validate_exact_length.rb +25 -0
  12. data/lib/rspec_sequel/matchers/validate_format.rb +25 -0
  13. data/lib/rspec_sequel/matchers/validate_includes.rb +25 -0
  14. data/lib/rspec_sequel/matchers/validate_integer.rb +21 -0
  15. data/lib/rspec_sequel/matchers/validate_length_range.rb +25 -0
  16. data/lib/rspec_sequel/matchers/validate_max_length.rb +25 -0
  17. data/lib/rspec_sequel/matchers/validate_min_length.rb +25 -0
  18. data/lib/rspec_sequel/matchers/validate_not_string.rb +21 -0
  19. data/lib/rspec_sequel/matchers/validate_numeric.rb +21 -0
  20. data/lib/rspec_sequel/matchers/validate_presence.rb +21 -0
  21. data/lib/rspec_sequel/matchers/validate_unique.rb +33 -0
  22. data/lib/rspec_sequel/validation.rb +77 -0
  23. data/lib/rspec_sequel_matchers.rb +9 -0
  24. data/spec/have_column_matcher_spec.rb +89 -0
  25. data/spec/have_many_to_many_matcher_spec.rb +56 -0
  26. data/spec/have_many_to_one_matcher_spec.rb +55 -0
  27. data/spec/have_one_to_many_matcher_spec.rb +55 -0
  28. data/spec/migrations/001_create_items.rb +15 -0
  29. data/spec/migrations/002_create_comments.rb +17 -0
  30. data/spec/migrations/003_create_comments_items.rb +15 -0
  31. data/spec/spec_helper.rb +51 -0
  32. data/spec/validate_exact_length_matcher_spec.rb +88 -0
  33. data/spec/validate_format_matcher_spec.rb +88 -0
  34. data/spec/validate_includes_matcher_spec.rb +88 -0
  35. data/spec/validate_integer_matcher_spec.rb +77 -0
  36. data/spec/validate_length_range_matcher_spec.rb +88 -0
  37. data/spec/validate_max_length_matcher_spec.rb +88 -0
  38. data/spec/validate_min_length_matcher_spec.rb +88 -0
  39. data/spec/validate_not_string_matcher_spec.rb +77 -0
  40. data/spec/validate_numeric_matcher_spec.rb +77 -0
  41. data/spec/validate_presence_matcher_spec.rb +77 -0
  42. data/spec/validate_unique_matcher_spec.rb +79 -0
  43. metadata +134 -0
@@ -0,0 +1,15 @@
1
+ class CreateItems < Sequel::Migration
2
+
3
+ def up
4
+ create_table :items do
5
+ primary_key :id
6
+ String :name
7
+ Float :price
8
+ end
9
+ end
10
+
11
+ def down
12
+ drop_table :items
13
+ end
14
+
15
+ 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
@@ -0,0 +1,51 @@
1
+ require "spec"
2
+ require "rubygems"
3
+ require "sequel"
4
+ require "sequel/extensions/inflector"
5
+ require "sequel/extensions/migration"
6
+ require File.join(File.dirname(__FILE__), "..", "lib", "rspec_sequel_matchers")
7
+
8
+ # connect to an in-memory database
9
+ begin
10
+ Sequel.sqlite
11
+ rescue Sequel::AdapterNotFound
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?
30
+ end
31
+
32
+ Spec::Runner.configure do |config|
33
+ config.include(RspecSequel::Matchers)
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
41
+ end
42
+
43
+ # truncate all tables between each spec
44
+ config.after(:each) do
45
+ db = Sequel::Model.db
46
+ db.tables.each do |table_name|
47
+ db["TRUNCATE #{table_name}"]
48
+ end
49
+ end
50
+
51
+ end
@@ -0,0 +1,88 @@
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 length of :name is exactly 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 " + @matcher.description
49
+ @matcher.negative_failure_message.should == "expected Item to not " + @matcher.description
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 length of :name is exactly 4 with option(s) :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 " + @matcher.description
61
+ @matcher.negative_failure_message.should == "expected Item to not " + @matcher.description
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
+ explanation = " but called with option(s) :allow_nil => true instead"
67
+ @matcher.failure_message.should == "expected Item to " + @matcher.description + explanation
68
+ @matcher.negative_failure_message.should == "expected Item to not " + @matcher.description + explanation
69
+ end
70
+ it "should warn if invalid options are used" do
71
+ @matcher = validate_exact_length 4, :name, :allow_anything => true
72
+ @matcher.matches? subject
73
+ explanation = " but option :allow_anything is not valid"
74
+ @matcher.failure_message.should == "expected Item to " + @matcher.description + explanation
75
+ @matcher.negative_failure_message.should == "expected Item to not " + @matcher.description + explanation
76
+ end
77
+ end
78
+ end
79
+
80
+ describe "matchers" do
81
+ it{ should validate_exact_length(4, :name) }
82
+ it{ should validate_exact_length(4, :name, :allow_nil => true) }
83
+ it{ should_not validate_exact_length(4, :price) }
84
+ it{ should_not validate_exact_length(3, :name) }
85
+ it{ should_not validate_exact_length(4, :name, :allow_blank => true) }
86
+ end
87
+
88
+ end
@@ -0,0 +1,88 @@
1
+ require File.dirname(__FILE__) + "/spec_helper"
2
+
3
+ describe "validate_format_matcher" do
4
+
5
+ before :all do
6
+ define_model :item do
7
+ plugin :validation_helpers
8
+ def validate
9
+ validates_format /[abc]+/, :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_format
20
+ }.should raise_error(ArgumentError)
21
+ end
22
+ it "should require additionnal parameters" do
23
+ lambda{
24
+ @matcher = validate_format :name
25
+ }.should raise_error(ArgumentError)
26
+ end
27
+ it "should refuse invalid additionnal parameters" do
28
+ lambda{
29
+ @matcher = validate_format :id, :name
30
+ }.should raise_error(ArgumentError)
31
+ end
32
+ it "should accept valid additionnal parameters" do
33
+ lambda{
34
+ @matcher = validate_format /[abc]+/, :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_format /[abc]+/, :name
43
+ @matcher.description.should == "validate format of :name against /[abc]+/"
44
+ end
45
+ it "should set failure messages" do
46
+ @matcher = validate_format /[abc]+/, :name
47
+ @matcher.matches? subject
48
+ @matcher.failure_message.should == "expected Item to " + @matcher.description
49
+ @matcher.negative_failure_message.should == "expected Item to not " + @matcher.description
50
+ end
51
+ end
52
+ describe "with options" do
53
+ it "should contain a description" do
54
+ @matcher = validate_format /[abc]+/, :name, :allow_nil => true
55
+ @matcher.description.should == "validate format of :name against /[abc]+/ with option(s) :allow_nil => true"
56
+ end
57
+ it "should set failure messages" do
58
+ @matcher = validate_format /[abc]+/, :price, :allow_nil => true
59
+ @matcher.matches? subject
60
+ @matcher.failure_message.should == "expected Item to " + @matcher.description
61
+ @matcher.negative_failure_message.should == "expected Item to not " + @matcher.description
62
+ end
63
+ it "should explicit used options if different than expected" do
64
+ @matcher = validate_format /[abc]+/, :name, :allow_blank => true
65
+ @matcher.matches? subject
66
+ explanation = " but called with option(s) :allow_nil => true instead"
67
+ @matcher.failure_message.should == "expected Item to " + @matcher.description + explanation
68
+ @matcher.negative_failure_message.should == "expected Item to not " + @matcher.description + explanation
69
+ end
70
+ it "should warn if invalid options are used" do
71
+ @matcher = validate_format /[abc]+/, :name, :allow_anything => true
72
+ @matcher.matches? subject
73
+ explanation = " but option :allow_anything is not valid"
74
+ @matcher.failure_message.should == "expected Item to " + @matcher.description + explanation
75
+ @matcher.negative_failure_message.should == "expected Item to not " + @matcher.description + explanation
76
+ end
77
+ end
78
+ end
79
+
80
+ describe "matchers" do
81
+ it{ should validate_format(/[abc]+/, :name) }
82
+ it{ should validate_format(/[abc]+/, :name, :allow_nil => true) }
83
+ it{ should_not validate_format(/[abc]+/, :price) }
84
+ it{ should_not validate_format(/[abc]/, :name) }
85
+ it{ should_not validate_format(/[abc]+/, :name, :allow_blank => true) }
86
+ end
87
+
88
+ end
@@ -0,0 +1,88 @@
1
+ require File.dirname(__FILE__) + "/spec_helper"
2
+
3
+ describe "validate_includes_matcher" do
4
+
5
+ before :all do
6
+ define_model :item do
7
+ plugin :validation_helpers
8
+ def validate
9
+ validates_includes ["Joseph", "Jonathan"], :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_includes
20
+ }.should raise_error(ArgumentError)
21
+ end
22
+ it "should require additionnal parameters" do
23
+ lambda{
24
+ @matcher = validate_includes :name
25
+ }.should raise_error(ArgumentError)
26
+ end
27
+ it "should refuse invalid additionnal parameters" do
28
+ lambda{
29
+ @matcher = validate_includes :id, :name
30
+ }.should raise_error(ArgumentError)
31
+ end
32
+ it "should accept valid additionnal parameters" do
33
+ lambda{
34
+ @matcher = validate_includes ["Joseph", "Jonathan"], :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_includes ["Joseph", "Jonathan"], :name
43
+ @matcher.description.should == 'validate that :name is included in ["Joseph", "Jonathan"]'
44
+ end
45
+ it "should set failure messages" do
46
+ @matcher = validate_includes ["Joseph", "Jonathan"], :name
47
+ @matcher.matches? subject
48
+ @matcher.failure_message.should == "expected Item to " + @matcher.description
49
+ @matcher.negative_failure_message.should == "expected Item to not " + @matcher.description
50
+ end
51
+ end
52
+ describe "with options" do
53
+ it "should contain a description" do
54
+ @matcher = validate_includes ["Joseph", "Jonathan"], :name, :allow_nil => true
55
+ @matcher.description.should == 'validate that :name is included in ["Joseph", "Jonathan"] with option(s) :allow_nil => true'
56
+ end
57
+ it "should set failure messages" do
58
+ @matcher = validate_includes ["Joseph", "Jonathan"], :price, :allow_nil => true
59
+ @matcher.matches? subject
60
+ @matcher.failure_message.should == "expected Item to " + @matcher.description
61
+ @matcher.negative_failure_message.should == "expected Item to not " + @matcher.description
62
+ end
63
+ it "should explicit used options if different than expected" do
64
+ @matcher = validate_includes ["Joseph", "Jonathan"], :name, :allow_blank => true
65
+ @matcher.matches? subject
66
+ explanation = " but called with option(s) :allow_nil => true instead"
67
+ @matcher.failure_message.should == "expected Item to " + @matcher.description + explanation
68
+ @matcher.negative_failure_message.should == "expected Item to not " + @matcher.description + explanation
69
+ end
70
+ it "should warn if invalid options are used" do
71
+ @matcher = validate_includes ["Joseph", "Jonathan"], :name, :allow_anything => true
72
+ @matcher.matches? subject
73
+ explanation = " but option :allow_anything is not valid"
74
+ @matcher.failure_message.should == "expected Item to " + @matcher.description + explanation
75
+ @matcher.negative_failure_message.should == "expected Item to not " + @matcher.description + explanation
76
+ end
77
+ end
78
+ end
79
+
80
+ describe "matchers" do
81
+ it{ should validate_includes(["Joseph", "Jonathan"], :name) }
82
+ it{ should validate_includes(["Joseph", "Jonathan"], :name, :allow_nil => true) }
83
+ it{ should_not validate_includes(["Joseph", "Jonathan"], :price) }
84
+ it{ should_not validate_includes(["Joseph", "Jonathan", "Alice"], :name) }
85
+ it{ should_not validate_includes(["Joseph", "Jonathan"], :name, :allow_blank => true) }
86
+ end
87
+
88
+ end
@@ -0,0 +1,77 @@
1
+ require File.dirname(__FILE__) + "/spec_helper"
2
+
3
+ describe "validate_integer_matcher" do
4
+
5
+ before :all do
6
+ define_model :item do
7
+ plugin :validation_helpers
8
+ def validate
9
+ validates_integer [:id, :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_integer
20
+ }.should raise_error(ArgumentError)
21
+ end
22
+ it "should refuse additionnal parameters" do
23
+ lambda{
24
+ @matcher = validate_integer :name, :id
25
+ }.should raise_error(ArgumentError)
26
+ end
27
+ end
28
+
29
+ describe "messages" do
30
+ describe "without option" do
31
+ it "should contain a description" do
32
+ @matcher = validate_integer :name
33
+ @matcher.description.should == "validate that :name is a valid integer"
34
+ end
35
+ it "should set failure messages" do
36
+ @matcher = validate_integer :name
37
+ @matcher.matches? subject
38
+ @matcher.failure_message.should == "expected Item to " + @matcher.description
39
+ @matcher.negative_failure_message.should == "expected Item to not " + @matcher.description
40
+ end
41
+ end
42
+ describe "with options" do
43
+ it "should contain a description" do
44
+ @matcher = validate_integer :name, :allow_nil => true
45
+ @matcher.description.should == "validate that :name is a valid integer with option(s) :allow_nil => true"
46
+ end
47
+ it "should set failure messages" do
48
+ @matcher = validate_integer :price, :allow_nil => true
49
+ @matcher.matches? subject
50
+ @matcher.failure_message.should == "expected Item to " + @matcher.description
51
+ @matcher.negative_failure_message.should == "expected Item to not " + @matcher.description
52
+ end
53
+ it "should explicit used options if different than expected" do
54
+ @matcher = validate_integer :name, :allow_blank => true
55
+ @matcher.matches? subject
56
+ explanation = " but called with option(s) :allow_nil => true instead"
57
+ @matcher.failure_message.should == "expected Item to " + @matcher.description + explanation
58
+ @matcher.negative_failure_message.should == "expected Item to not " + @matcher.description + explanation
59
+ end
60
+ it "should warn if invalid options are used" do
61
+ @matcher = validate_integer :name, :allow_anything => true
62
+ @matcher.matches? subject
63
+ explanation = " but option :allow_anything is not valid"
64
+ @matcher.failure_message.should == "expected Item to " + @matcher.description + explanation
65
+ @matcher.negative_failure_message.should == "expected Item to not " + @matcher.description + explanation
66
+ end
67
+ end
68
+ end
69
+
70
+ describe "matchers" do
71
+ it{ should validate_integer(:name) }
72
+ it{ should validate_integer(:name, :allow_nil => true) }
73
+ it{ should_not validate_integer(:price) }
74
+ it{ should_not validate_integer(:name, :allow_blank => true) }
75
+ end
76
+
77
+ end