JonathanTron-rspec_sequel_matchers 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Jonathan Tron, Joseph Halter
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,22 @@
1
+ = rspec_sequel_matchers
2
+
3
+ Some Sequel Matchers for RSpec, using no other gem than rspec and sequel themself.
4
+ As a consequence, you can use these matchers with Rails, Sinatra or any other framework.
5
+
6
+ Validation matchers assume that you're using the recommanded validation_helpers plugin.
7
+
8
+ == Install
9
+
10
+ sudo gem install JonathanTron-rspec_sequel_matchers
11
+
12
+ == Example usage
13
+
14
+ describe Item do
15
+ it{ should have_column :name, :type => String }
16
+ it{ should_not have_column :wrong_name }
17
+ it{ should_validate_presence :name, :allow_nil => true }
18
+ end
19
+
20
+ == Copyright
21
+
22
+ Copyright (c) 2009 Jonathan Tron - Joseph Halter. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,48 @@
1
+ require "rubygems"
2
+ require "rake"
3
+
4
+ begin
5
+ require "jeweler"
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "rspec_sequel_matchers"
8
+ gem.summary = %Q{TODO}
9
+ gem.email = "jonathan@tron.name"
10
+ gem.homepage = "http://github.com/JonathanTron/rspec_sequel_matchers"
11
+ gem.authors = ["Jonathan Tron", "Joseph Halter"]
12
+ gem.add_dependency "rspec"
13
+ gem.add_dependency "sequel"
14
+
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ rescue LoadError
18
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
19
+ end
20
+
21
+ require "spec/rake/spectask"
22
+ Spec::Rake::SpecTask.new(:spec) do |spec|
23
+ spec.libs << "lib" << "spec"
24
+ spec.spec_files = FileList["spec/**/*_spec.rb"]
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << "lib" << "spec"
29
+ spec.pattern = "spec/**/*_spec.rb"
30
+ spec.rcov = true
31
+ end
32
+
33
+ task :default => :spec
34
+
35
+ require "rake/rdoctask"
36
+ Rake::RDocTask.new do |rdoc|
37
+ if File.exist?("VERSION.yml")
38
+ config = YAML.load(File.read("VERSION.yml"))
39
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
40
+ else
41
+ version = ""
42
+ end
43
+
44
+ rdoc.rdoc_dir = "rdoc"
45
+ rdoc.title = "test #{version}"
46
+ rdoc.rdoc_files.include("README*")
47
+ rdoc.rdoc_files.include("lib/**/*.rb")
48
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,32 @@
1
+ module RspecSequel
2
+
3
+ class Base
4
+ def initialize(attribute, options={})
5
+ @attribute = attribute.to_sym
6
+ @options = options
7
+ @description = []
8
+ end
9
+ def matches?(target)
10
+ @suffix = []
11
+ if target.is_a?(Sequel::Model)
12
+ @prefix = "expected #{target.inspect} to"
13
+ valid?(target.db, target, target.class, @attribute, @options)
14
+ else
15
+ name = target.name
16
+ name = target.table_name if name.nil? || name==""
17
+ @prefix = "expected #{name} to"
18
+ valid?(target.db, target.new, target, @attribute, @options)
19
+ end
20
+ end
21
+ def failure_message
22
+ [@prefix, description, @suffix].flatten.compact.join(" ")
23
+ end
24
+ def negative_failure_message
25
+ [@prefix, "not", description, @suffix].flatten.compact.join(" ")
26
+ end
27
+ def hash_to_nice_string(hash)
28
+ hash.sort.collect{|param| param.join(" => ")}.join(", ")
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,35 @@
1
+ module RspecSequel
2
+ module Matchers
3
+
4
+ class HaveColumnMatcher < RspecSequel::Base
5
+ def description
6
+ desc = "have a column :#{@attribute}"
7
+ desc << " with type #{@options[:type]}" if @options[:type]
8
+ desc
9
+ end
10
+
11
+ def valid?(db, i, c, attribute, options)
12
+
13
+ # check column existance
14
+ col = db.schema(c.table_name).detect{|col| col[0]==attribute}
15
+ matching = !col.nil?
16
+
17
+ # check type
18
+ if @options[:type]
19
+ expected = db.send(:type_literal, {:type => options[:type]}).to_s
20
+ if matching
21
+ found = [col[1][:type].to_s, col[1][:db_type].to_s]
22
+ @suffix << "(type found: #{found.uniq.join(", ")})"
23
+ matching &&= found.include?(expected)
24
+ end
25
+ end
26
+ matching
27
+ end
28
+ end
29
+
30
+ def have_column(*args)
31
+ HaveColumnMatcher.new(*args)
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,39 @@
1
+ module RspecSequel
2
+ module Matchers
3
+
4
+ class ValidatePresenceMatcher < RspecSequel::Base
5
+ def description
6
+ desc = "validate presence of :#{@attribute}"
7
+ unless @options.empty?
8
+ desc << " with #{hash_to_nice_string @options}"
9
+ end
10
+ desc
11
+ end
12
+
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
31
+ end
32
+ end
33
+
34
+ def validate_presence(*args)
35
+ ValidatePresenceMatcher.new(*args)
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,7 @@
1
+ # Load base
2
+ require File.join(File.dirname(__FILE__), "rspec_sequel", "base")
3
+
4
+ # Add matchers
5
+ Dir[File.join(File.dirname(__FILE__), "rspec_sequel", "matchers", "*.rb")].each do |file|
6
+ require file
7
+ end
@@ -0,0 +1,60 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{rspec_sequel_matchers}
5
+ s.version = "0.0.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Jonathan Tron", "Joseph Halter"]
9
+ s.date = %q{2009-08-05}
10
+ s.email = %q{jonathan@tron.name}
11
+ s.extra_rdoc_files = [
12
+ "LICENSE",
13
+ "README.rdoc"
14
+ ]
15
+ s.files = [
16
+ ".document",
17
+ ".gitignore",
18
+ "LICENSE",
19
+ "README.rdoc",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "lib/rspec_sequel/base.rb",
23
+ "lib/rspec_sequel/matchers/have_column.rb",
24
+ "lib/rspec_sequel/matchers/validate_presence.rb",
25
+ "lib/rspec_sequel_matchers.rb",
26
+ "rspec_sequel_matchers.gemspec",
27
+ "spec/have_column_matcher_spec.rb",
28
+ "spec/migrations/001_create_items.rb",
29
+ "spec/spec_helper.rb",
30
+ "spec/validate_presence_matcher_spec.rb"
31
+ ]
32
+ s.has_rdoc = true
33
+ s.homepage = %q{http://github.com/JonathanTron/rspec_sequel_matchers}
34
+ s.rdoc_options = ["--charset=UTF-8"]
35
+ s.require_paths = ["lib"]
36
+ s.rubygems_version = %q{1.3.1}
37
+ s.summary = %q{TODO}
38
+ s.test_files = [
39
+ "spec/have_column_matcher_spec.rb",
40
+ "spec/migrations/001_create_items.rb",
41
+ "spec/spec_helper.rb",
42
+ "spec/validate_presence_matcher_spec.rb"
43
+ ]
44
+
45
+ if s.respond_to? :specification_version then
46
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
47
+ s.specification_version = 2
48
+
49
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
50
+ s.add_runtime_dependency(%q<rspec>, [">= 0"])
51
+ s.add_runtime_dependency(%q<sequel>, [">= 0"])
52
+ else
53
+ s.add_dependency(%q<rspec>, [">= 0"])
54
+ s.add_dependency(%q<sequel>, [">= 0"])
55
+ end
56
+ else
57
+ s.add_dependency(%q<rspec>, [">= 0"])
58
+ s.add_dependency(%q<sequel>, [">= 0"])
59
+ end
60
+ end
@@ -0,0 +1,87 @@
1
+ require File.dirname(__FILE__) + "/spec_helper"
2
+
3
+ class Item < Sequel::Model
4
+ end
5
+
6
+ describe "have_column_matcher" do
7
+
8
+ subject{ Item }
9
+
10
+ describe "messages" do
11
+ describe "without type" do
12
+ it "should contain a description" do
13
+ @matcher = have_column :name
14
+ @matcher.description.should == "have a column :name"
15
+ end
16
+ it "should set failure messages" do
17
+ @matcher = have_column :name
18
+ @matcher.matches? subject
19
+ @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
+ end
22
+ end
23
+ describe "with type as symbol" do
24
+ it "should contain a description" do
25
+ @matcher = have_column :name, :type => :string
26
+ @matcher.description.should == "have a column :name with type string"
27
+ end
28
+ it "should set failure messages" do
29
+ @matcher = have_column :password, :type => :string
30
+ @matcher.matches? subject
31
+ @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
+ end
34
+ end
35
+ describe "with type as object" do
36
+ it "should contain a description" do
37
+ @matcher = have_column :name, :type => String
38
+ @matcher.description.should == "have a column :name with type String"
39
+ end
40
+ it "should set failure messages" do
41
+ @matcher = have_column :password, :type => String
42
+ @matcher.matches? subject
43
+ @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
+ end
46
+ it "should explicit found type if different than expected" do
47
+ @matcher = have_column :name, :type => Integer
48
+ @matcher.matches? subject
49
+ @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
+ end
52
+ end
53
+ describe "on anonymous Sequel::Model class" do
54
+ it "should set failure messages" do
55
+ @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"
59
+ end
60
+ end
61
+ describe "on Sequel::Model class" do
62
+ it "should set failure messages" do
63
+ @matcher = have_column :password
64
+ @matcher.matches? Item
65
+ @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
+ end
68
+ end
69
+ describe "on Sequel::Model instance" do
70
+ it "should set failure messages" do
71
+ @matcher = have_column :password
72
+ @matcher.matches? Item.new
73
+ @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
+ end
76
+ end
77
+ end
78
+
79
+ describe "matchers" do
80
+ it{ should have_column(:name) }
81
+ it{ should have_column(:name, :type => :string) }
82
+ it{ should have_column(:name, :type => String) }
83
+ it{ should_not have_column(:password) }
84
+ it{ should_not have_column(:name, :type => :integer) }
85
+ end
86
+
87
+ end
@@ -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,32 @@
1
+ require "spec"
2
+ require "rubygems"
3
+ require "sequel"
4
+ require "sequel/extensions/migration"
5
+ require File.join(File.dirname(__FILE__), "..", "lib", "rspec_sequel_matchers")
6
+
7
+ # connect to an in-memory database
8
+ begin
9
+ Sequel.sqlite
10
+ rescue Sequel::AdapterNotFound
11
+ puts "sqlite not available. Install it with: sudo gem install sqlite3-ruby"
12
+ end
13
+
14
+ Spec::Runner.configure do |config|
15
+ 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"))
23
+ end
24
+
25
+ config.after(:each) do
26
+ db = Sequel::Model.db
27
+ db.tables.each do |table_name|
28
+ db["TRUNCATE #{table_name}"]
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,54 @@
1
+ require File.dirname(__FILE__) + "/spec_helper"
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
+ describe "validate_presence_matcher" do
11
+
12
+ subject{ Item }
13
+
14
+ describe "messages" do
15
+ describe "without option" do
16
+ it "should contain a description" do
17
+ @matcher = validate_presence :name
18
+ @matcher.description.should == "validate presence of :name"
19
+ end
20
+ it "should set failure messages" do
21
+ @matcher = validate_presence :name
22
+ @matcher.matches? subject
23
+ @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"
25
+ end
26
+ end
27
+ describe "with options" do
28
+ it "should contain a description" do
29
+ @matcher = validate_presence :name, :allow_nil => true
30
+ @matcher.description.should == "validate presence of :name with allow_nil => true"
31
+ end
32
+ it "should set failure messages" do
33
+ @matcher = validate_presence :price, :allow_nil => true
34
+ @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"
37
+ end
38
+ it "should explicit used options if different than expected" do
39
+ @matcher = validate_presence :name, :allow_blank => true
40
+ @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)"
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "matchers" do
48
+ it{ should validate_presence(:name) }
49
+ it{ should validate_presence(:name, :allow_nil => true) }
50
+ it{ should_not validate_presence(:price) }
51
+ it{ should_not validate_presence(:name, :allow_blank => true) }
52
+ end
53
+
54
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: JonathanTron-rspec_sequel_matchers
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jonathan Tron
8
+ - Joseph Halter
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-08-05 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rspec
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: sequel
28
+ type: :runtime
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ version:
36
+ description:
37
+ email: jonathan@tron.name
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files:
43
+ - LICENSE
44
+ - README.rdoc
45
+ files:
46
+ - .document
47
+ - .gitignore
48
+ - LICENSE
49
+ - README.rdoc
50
+ - Rakefile
51
+ - VERSION
52
+ - lib/rspec_sequel/base.rb
53
+ - lib/rspec_sequel/matchers/have_column.rb
54
+ - lib/rspec_sequel/matchers/validate_presence.rb
55
+ - lib/rspec_sequel_matchers.rb
56
+ - rspec_sequel_matchers.gemspec
57
+ - spec/have_column_matcher_spec.rb
58
+ - spec/migrations/001_create_items.rb
59
+ - spec/spec_helper.rb
60
+ - spec/validate_presence_matcher_spec.rb
61
+ has_rdoc: true
62
+ homepage: http://github.com/JonathanTron/rspec_sequel_matchers
63
+ licenses:
64
+ post_install_message:
65
+ rdoc_options:
66
+ - --charset=UTF-8
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ version:
81
+ requirements: []
82
+
83
+ rubyforge_project:
84
+ rubygems_version: 1.3.5
85
+ signing_key:
86
+ specification_version: 2
87
+ summary: TODO
88
+ test_files:
89
+ - spec/have_column_matcher_spec.rb
90
+ - spec/migrations/001_create_items.rb
91
+ - spec/spec_helper.rb
92
+ - spec/validate_presence_matcher_spec.rb