svenaas-woulda 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.textile +86 -0
- data/Rakefile +28 -0
- data/VERSION.yml +4 -0
- data/lib/woulda/acts_as_ferret/macros.rb +24 -0
- data/lib/woulda/acts_as_ferret.rb +6 -0
- data/lib/woulda/acts_as_list/macros.rb +20 -0
- data/lib/woulda/acts_as_list.rb +6 -0
- data/lib/woulda/acts_as_paranoid/macros.rb +39 -0
- data/lib/woulda/acts_as_paranoid.rb +6 -0
- data/lib/woulda/acts_as_solr/macros.rb +49 -0
- data/lib/woulda/acts_as_solr.rb +6 -0
- data/lib/woulda/acts_as_state_machine/macros_new.rb +87 -0
- data/lib/woulda/acts_as_state_machine/macros_old.rb +87 -0
- data/lib/woulda/acts_as_state_machine.rb +7 -0
- data/lib/woulda/acts_as_taggable_on_steroids/macros.rb +18 -0
- data/lib/woulda/acts_as_taggable_on_steroids.rb +6 -0
- data/lib/woulda/acts_as_xapian/macros.rb +27 -0
- data/lib/woulda/acts_as_xapian.rb +6 -0
- data/lib/woulda/attachment_fu/macros.rb +27 -0
- data/lib/woulda/attachment_fu.rb +6 -0
- data/lib/woulda/enumerations_mixin/macros.rb +26 -0
- data/lib/woulda/enumerations_mixin.rb +6 -0
- data/lib/woulda/paperclip/macros.rb +22 -0
- data/lib/woulda/paperclip.rb +6 -0
- data/lib/woulda/should_raise/macros.rb +102 -0
- data/lib/woulda/should_raise.rb +6 -0
- data/lib/woulda/will_paginate/macros.rb +18 -0
- data/lib/woulda/will_paginate.rb +6 -0
- data/lib/woulda.rb +17 -0
- data/shoulda_macros/woulda_macros.rb +1 -0
- metadata +104 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Sean Hussey and Josh Nichols
|
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.textile
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
h1. woulda
|
2
|
+
|
3
|
+
Testing is love. Especially when done with "Shoulda":http://thoughtbot.com/projects/shoulda. Shoulda makes testing your Rails app pretty easy.
|
4
|
+
|
5
|
+
There are tons of Rails plugins and gems out there. It should be easy to test your Rails app that uses these as well. That kind of support doesn't really belong in Shoulda itself, though.
|
6
|
+
|
7
|
+
That's where Woulda comes in.
|
8
|
+
|
9
|
+
h2. Installing
|
10
|
+
|
11
|
+
It's available as a gem: <pre>gem install seanhussey-woulda --source http://gems.github.com</pre>
|
12
|
+
|
13
|
+
Use it in a Rails app by placing in config/environments/test.rb:
|
14
|
+
|
15
|
+
<pre>config.gem 'seanhussey-woulda', :lib => 'woulda', :source => 'http://gems.github.com'</pre>
|
16
|
+
|
17
|
+
Woulda requires "shoulda":http://github.com/thoughtbot/shoulda/tree/master >= 2.0.0.
|
18
|
+
|
19
|
+
h2. Included Macros
|
20
|
+
|
21
|
+
<pre><code># acts_as_ferret
|
22
|
+
class PostTest < Test::Unit::TestCase
|
23
|
+
should_act_as_ferret :title, :contents
|
24
|
+
end
|
25
|
+
|
26
|
+
# acts_as_list
|
27
|
+
class NewsItemTest < Test::Unit::TestCase
|
28
|
+
should_act_as_list
|
29
|
+
end
|
30
|
+
|
31
|
+
# acts_as_paranoid
|
32
|
+
class DocumentTest < Test::Unit::TestCase
|
33
|
+
should_act_as_paranoid
|
34
|
+
end
|
35
|
+
|
36
|
+
# acts_as_taggable_on_steroids
|
37
|
+
class PersonTest < Test::Unit::TestCase
|
38
|
+
should_act_as_taggable_on_steroids
|
39
|
+
end
|
40
|
+
|
41
|
+
# attachment_fu
|
42
|
+
class ImageTest < Test::Unit::TestCase
|
43
|
+
should_have_attachment :content_type => :image
|
44
|
+
end
|
45
|
+
|
46
|
+
# enumeration_mixin
|
47
|
+
class RoleTest < Test::Unit::TestCase
|
48
|
+
should_act_as_enumerated
|
49
|
+
end
|
50
|
+
|
51
|
+
# paperclip
|
52
|
+
class UserTest < Test::Unit::TestCase
|
53
|
+
should_have_attached_file :avatar
|
54
|
+
end
|
55
|
+
|
56
|
+
# will_paginate
|
57
|
+
class PostTest < Test::Unit::TestCase
|
58
|
+
should_have_per_page 10
|
59
|
+
end
|
60
|
+
|
61
|
+
# acts_as_solr
|
62
|
+
class ProductTest < Test::Unit::TestCase
|
63
|
+
should_act_as_solr :name, :price
|
64
|
+
end
|
65
|
+
|
66
|
+
# acts_as_xapian
|
67
|
+
class ProductTest < Test::Unit::TestCase
|
68
|
+
should_act_as_xapian :name, :description
|
69
|
+
end
|
70
|
+
|
71
|
+
# acts_as_state_machine
|
72
|
+
class OrderTest < Test::Unit::TestCase
|
73
|
+
should_act_as_state_machine :initial => :open, :states => [:closed], :events => {:close_order => {:to => :closed, :from :open}}
|
74
|
+
end</code></pre>
|
75
|
+
|
76
|
+
h2. The source
|
77
|
+
|
78
|
+
The source is available from "GitHub":http://github.com/seanhussey/woulda/tree/master.
|
79
|
+
|
80
|
+
Clone it: <pre>git clone git://github.com/seanhussey/woulda.git</pre>
|
81
|
+
|
82
|
+
h2. Credit
|
83
|
+
|
84
|
+
Written by "Sean Hussey":mailto:sean@seanhussey.com and "Josh Nichols":http://technicalpickles.com
|
85
|
+
|
86
|
+
Copyright 2008 Sean Hussey and Josh Nichols.
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'jeweler'
|
7
|
+
Jeweler::Tasks.new do |s|
|
8
|
+
s.name = "woulda"
|
9
|
+
s.summary = "woulda is a home for shoulda macros that don't belong in the main shoulda library"
|
10
|
+
s.email = ["sean@seanhussey.com", "josh@technicalpickles.com"]
|
11
|
+
s.homepage = "http://github.com/seanhussey/woulda"
|
12
|
+
s.description = "TODO"
|
13
|
+
s.authors = ["Sean Hussey", "Josh Nichols"]
|
14
|
+
s.add_dependency "thoughtbot-shoulda", ">= 2.10.2"
|
15
|
+
s.rubyforge_project = "woulda"
|
16
|
+
s.files = FileList["[A-Z]*", "{shoulda_macros}/**/*", "lib/**/*"]
|
17
|
+
end
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Run all tests"
|
23
|
+
Rake::TestTask.new(:test) do |t|
|
24
|
+
t.pattern = 'test/**/*_test.rb'
|
25
|
+
t.verbose = true
|
26
|
+
end
|
27
|
+
|
28
|
+
task :default => :test
|
data/VERSION.yml
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module Woulda
|
2
|
+
module ActsAsFerret
|
3
|
+
module Macros
|
4
|
+
# should_act_as_ferret :any, :fields, :i_may, :have, :specified
|
5
|
+
# Original source: http://www.soyunperdedor.com/node/34
|
6
|
+
def should_act_as_ferret(*fields)
|
7
|
+
klass = self.name.gsub(/Test$/, '').constantize
|
8
|
+
|
9
|
+
should "include ActsAsFerret methods" do
|
10
|
+
assert klass.extended_by.include?(ActsAsFerret::ClassMethods)
|
11
|
+
assert klass.include?(ActsAsFerret::InstanceMethods)
|
12
|
+
assert klass.include?(ActsAsFerret::MoreLikeThis::InstanceMethods)
|
13
|
+
assert klass.include?(ActsAsFerret::ResultAttributes)
|
14
|
+
end
|
15
|
+
|
16
|
+
fields.each do |f|
|
17
|
+
should "create an index for field named #{f}" do
|
18
|
+
assert klass.aaf_configuration[:fields].include?(f)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Woulda
|
2
|
+
module ActsAsList
|
3
|
+
module Macros
|
4
|
+
# Original source: http://www.soyunperdedor.com/node/34
|
5
|
+
def should_act_as_list
|
6
|
+
klass = self.name.gsub(/Test$/, '').constantize
|
7
|
+
|
8
|
+
context "To support acts_as_list" do
|
9
|
+
should_have_db_column('position', :type => :integer)
|
10
|
+
end
|
11
|
+
|
12
|
+
should "include ActsAsList methods" do
|
13
|
+
assert klass.include?(ActiveRecord::Acts::List::InstanceMethods)
|
14
|
+
end
|
15
|
+
|
16
|
+
should_have_instance_methods :acts_as_list_class, :position_column, :scope_condition
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Woulda
|
2
|
+
module ActsAsParanoid
|
3
|
+
module Macros
|
4
|
+
def should_act_as_paranoid
|
5
|
+
klass = described_type
|
6
|
+
should_have_db_column :deleted_at
|
7
|
+
|
8
|
+
context "A #{klass.name}" do
|
9
|
+
should "be paranoid (it will not be deleted from the database)" do
|
10
|
+
assert klass.paranoid?
|
11
|
+
assert klass.included_modules.include?(Caboose::Acts::Paranoid)
|
12
|
+
end
|
13
|
+
|
14
|
+
should "not have a value for deleted_at" do
|
15
|
+
assert object = klass.find(:first)
|
16
|
+
assert_nil object.deleted_at
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when destroyed" do
|
20
|
+
setup do
|
21
|
+
assert object = klass.find(:first), "This context requires there to be an existing #{klass}"
|
22
|
+
@deleted_id = object.id
|
23
|
+
object.destroy
|
24
|
+
end
|
25
|
+
|
26
|
+
should "not be found" do
|
27
|
+
assert_raise(ActiveRecord::RecordNotFound) { klass.find(@deleted_id) }
|
28
|
+
end
|
29
|
+
|
30
|
+
should "still exist in the database" do
|
31
|
+
deleted_object = klass.find_with_deleted(@deleted_id)
|
32
|
+
assert_not_nil deleted_object.deleted_at
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Woulda
|
2
|
+
module ActsAsSolr
|
3
|
+
module Macros
|
4
|
+
def should_act_as_solr(opts={})
|
5
|
+
klass = described_type
|
6
|
+
|
7
|
+
associations = get_options!([opts], :associations)
|
8
|
+
|
9
|
+
associations ||= []
|
10
|
+
|
11
|
+
context "A #{klass.name}" do
|
12
|
+
# should "include the ActsAsSolr::ParserMethods module" do
|
13
|
+
# assert klass.included_modules.include?(ActsAsSolr::ParserMethods)
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# should "include the ActsAsSolr::CommonMethods module" do
|
17
|
+
# assert klass.included_modules.include?(ActsAsSolr::CommonMethods)
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# should "include the ActsAsSolr::InstanceMethods module" do
|
21
|
+
# assert klass.included_modules.include?(ActsAsSolr::InstanceMethods)
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# should "be extended by the ActsAsSolr::ClassMethods module" do
|
25
|
+
# assert klass.extended_by.include?(ActsAsSolr::ClassMethods)
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# should "be extended by the ActsAsSolr::ParserMethods module" do
|
29
|
+
# assert klass.extended_by.include?(ActsAsSolr::ParserMethods)
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# should "be extended by the ActsAsSolr::CommonMethods module" do
|
33
|
+
# assert klass.extended_by.include?(ActsAsSolr::CommonMethods)
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# should "be extended by the ActsAsSolr::PaginationExtension module" do
|
37
|
+
# assert klass.extended_by.include?(ActsAsSolr::PaginationExtension)
|
38
|
+
# end
|
39
|
+
|
40
|
+
associations.each do |association|
|
41
|
+
should "include the #{association.to_s} association in solr indexing" do
|
42
|
+
klass.configuration[:include].include?(association)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Woulda
|
2
|
+
module ActsAsStateMachine
|
3
|
+
module Macros
|
4
|
+
# Example:
|
5
|
+
#
|
6
|
+
# class Order < ActiveRecord::Base
|
7
|
+
# acts_as_state_machine :initial => :open
|
8
|
+
#
|
9
|
+
# state :open
|
10
|
+
# state :closed
|
11
|
+
#
|
12
|
+
# event :close_order do
|
13
|
+
# transitions :to => :closed, :from => :open
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# class OrderTest < Test::Unit::TestCase
|
18
|
+
#
|
19
|
+
# # check the inital state
|
20
|
+
# should_act_as_state_machine :initial => :open
|
21
|
+
#
|
22
|
+
# # check states in addition to :initial
|
23
|
+
# should_act_as_state_machine :initial => :open, :states => [:closed]
|
24
|
+
#
|
25
|
+
# # check events and transitions
|
26
|
+
# should_act_as_state_machine :events => {:close_order => {:to => :closed, :from :open}}
|
27
|
+
#
|
28
|
+
# should_act_as_state_machine :initial => :open, :states => [:closed], :events => {:close_order => {:to => :closed, :from :open}}
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
def should_act_as_state_machine(opts={})
|
32
|
+
klass = described_type
|
33
|
+
|
34
|
+
initial_state, states, events, db_column = get_options!([opts], :initial, :states, :events, :column)
|
35
|
+
|
36
|
+
states ||= []
|
37
|
+
events ||= {}
|
38
|
+
db_column ||= :state
|
39
|
+
|
40
|
+
context "A #{klass.name}" do
|
41
|
+
|
42
|
+
should_have_db_column db_column
|
43
|
+
|
44
|
+
should "include the ActsAsStateMachine module" do
|
45
|
+
assert klass.included_modules.include?(AASM)
|
46
|
+
end
|
47
|
+
|
48
|
+
should "define ActsAsStateMachine class methods" do
|
49
|
+
assert klass.extended_by.include?(AASM::ClassMethods), "#{klass} doesn't define ActsAsStateMachine class methods"
|
50
|
+
end
|
51
|
+
|
52
|
+
should "define ActsAsStateMachine instance methods" do
|
53
|
+
assert klass.include?(AASM::InstanceMethods), "#{klass} doesn't define ActsAsStateMachine instance methods"
|
54
|
+
end
|
55
|
+
|
56
|
+
should "have an intital state of #{initial_state}" do
|
57
|
+
assert_equal initial_state, klass.aasm_initial_state, "#{klass} does not have an initial state of #{initial_state}"
|
58
|
+
end
|
59
|
+
|
60
|
+
states.each do |state|
|
61
|
+
should "include state #{state}" do
|
62
|
+
assert klass.aasm_states.map { |state| state.name}.include?(state), "#{klass} does not include state #{state}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
events.each do |event, transition|
|
67
|
+
|
68
|
+
should "define an event #{event}" do
|
69
|
+
assert klass.aasm_events.has_key?(event), "#{klass} does not define event #{event}"
|
70
|
+
end
|
71
|
+
|
72
|
+
to = transition[:to]
|
73
|
+
from = transition[:from].is_a?(Symbol) ? [transition[:from]] : transition[:from]
|
74
|
+
|
75
|
+
from.each do |from_state|
|
76
|
+
should "transition to #{to} from #{from_state} on event #{event}" do
|
77
|
+
assert_not_nil klass.aasm_events[event].instance_variable_get("@transitions").detect { |t| t.to == to && t.from == from_state }, "#{event} does not transition to #{to} from #{from_state}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Woulda
|
2
|
+
module ActsAsStateMachine
|
3
|
+
module Macros
|
4
|
+
# Example:
|
5
|
+
#
|
6
|
+
# class Order < ActiveRecord::Base
|
7
|
+
# acts_as_state_machine :initial => :open
|
8
|
+
#
|
9
|
+
# state :open
|
10
|
+
# state :closed
|
11
|
+
#
|
12
|
+
# event :close_order do
|
13
|
+
# transitions :to => :closed, :from => :open
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# class OrderTest < Test::Unit::TestCase
|
18
|
+
#
|
19
|
+
# # check the inital state
|
20
|
+
# should_act_as_state_machine :initial => :open
|
21
|
+
#
|
22
|
+
# # check states in addition to :initial
|
23
|
+
# should_act_as_state_machine :initial => :open, :states => [:closed]
|
24
|
+
#
|
25
|
+
# # check events and transitions
|
26
|
+
# should_act_as_state_machine :events => {:close_order => {:to => :closed, :from :open}}
|
27
|
+
#
|
28
|
+
# should_act_as_state_machine :initial => :open, :states => [:closed], :events => {:close_order => {:to => :closed, :from :open}}
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
def should_act_as_state_machine(opts={})
|
32
|
+
klass = described_type
|
33
|
+
|
34
|
+
initial_state, states, events, db_column = get_options!([opts], :initial, :states, :events, :column)
|
35
|
+
|
36
|
+
states ||= []
|
37
|
+
events ||= {}
|
38
|
+
db_column ||= :state
|
39
|
+
|
40
|
+
context "A #{klass.name}" do
|
41
|
+
|
42
|
+
should_have_db_column db_column
|
43
|
+
|
44
|
+
should "include the ActsAsStateMachine module" do
|
45
|
+
assert klass.included_modules.include?(ScottBarron::Acts::StateMachine)
|
46
|
+
end
|
47
|
+
|
48
|
+
should "define ActsAsStateMachine class methods" do
|
49
|
+
assert klass.extended_by.include?(ScottBarron::Acts::StateMachine::ClassMethods), "#{klass} doesn't define ActsAsStateMachine class methods"
|
50
|
+
end
|
51
|
+
|
52
|
+
should "define ActsAsStateMachine instance methods" do
|
53
|
+
assert klass.include?(ScottBarron::Acts::StateMachine::InstanceMethods), "#{klass} doesn't define ActsAsStateMachine instance methods"
|
54
|
+
end
|
55
|
+
|
56
|
+
should "have an intital state of #{initial_state}" do
|
57
|
+
assert_equal initial_state, klass.initial_state, "#{klass} does not have an initial state of #{initial_state}"
|
58
|
+
end
|
59
|
+
|
60
|
+
states.each do |state|
|
61
|
+
should "include state #{state}" do
|
62
|
+
assert klass.states.include?(state), "#{klass} does not include state #{state}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
events.each do |event, transition|
|
67
|
+
|
68
|
+
should "define an event #{event}" do
|
69
|
+
assert klass.transition_table.has_key?(event), "#{klass} does not define event #{event}"
|
70
|
+
end
|
71
|
+
|
72
|
+
to = transition[:to]
|
73
|
+
from = transition[:from].is_a?(Symbol) ? [transition[:from]] : transition[:from]
|
74
|
+
|
75
|
+
from.each do |from_state|
|
76
|
+
should "transition to #{to} from #{from_state} on event #{event}" do
|
77
|
+
assert_not_nil klass.transition_table[event].detect { |t| t.to == to && t.from == from_state }, "#{event} does not transition to #{to} from #{from_state}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
require 'shoulda'
|
2
|
+
require File.dirname(__FILE__) + '/acts_as_state_machine/macros_old' unless defined?(AASM)
|
3
|
+
require File.dirname(__FILE__) + '/acts_as_state_machine/macros_new' if defined?(AASM)
|
4
|
+
|
5
|
+
Test::Unit::TestCase.class_eval do
|
6
|
+
extend Woulda::ActsAsStateMachine::Macros
|
7
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Woulda
|
2
|
+
module ActsAsTaggableOnSteroids
|
3
|
+
module Macros
|
4
|
+
# Original source: http://www.soyunperdedor.com/node/34
|
5
|
+
def should_act_as_taggable_on_steroids
|
6
|
+
klass = self.name.gsub(/Test$/, '').constantize
|
7
|
+
|
8
|
+
should "include ActsAsTaggableOnSteroids methods" do
|
9
|
+
assert klass.extended_by.include?(ActiveRecord::Acts::Taggable::ClassMethods)
|
10
|
+
assert klass.extended_by.include?(ActiveRecord::Acts::Taggable::SingletonMethods)
|
11
|
+
assert klass.include?(ActiveRecord::Acts::Taggable::InstanceMethods)
|
12
|
+
end
|
13
|
+
|
14
|
+
should_have_many :taggings, :tags
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Woulda
|
2
|
+
module ActsAsXapian
|
3
|
+
module Macros
|
4
|
+
|
5
|
+
#
|
6
|
+
# should_act_as_xapian :name, :description
|
7
|
+
#
|
8
|
+
def should_act_as_xapian(*fields)
|
9
|
+
klass = described_type
|
10
|
+
|
11
|
+
context "A #{klass}" do
|
12
|
+
should "include ActsAsXapian methods" do
|
13
|
+
assert klass.include?(ActsAsXapian::InstanceMethods)
|
14
|
+
end
|
15
|
+
|
16
|
+
fields.each do |field|
|
17
|
+
should "index field #{field}" do
|
18
|
+
assert klass.xapian_options[:texts].include?(field)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Woulda
|
2
|
+
module AttachmentFu
|
3
|
+
module Macros
|
4
|
+
def should_have_attachment(options = {})
|
5
|
+
klass = described_type
|
6
|
+
|
7
|
+
should_have_db_columns :size, :content_type, :filename
|
8
|
+
if options[:content_type] == :image
|
9
|
+
should_have_db_columns :height, :width
|
10
|
+
end
|
11
|
+
|
12
|
+
should "define AttachmentFu class methods" do
|
13
|
+
# breakpoint
|
14
|
+
class_modules = (class << klass; included_modules; end)
|
15
|
+
assert class_modules.include?(Technoweenie::AttachmentFu::ClassMethods),
|
16
|
+
"#{klass} doesn't define AttachmentFu class methods"
|
17
|
+
end
|
18
|
+
|
19
|
+
should "define AttachmentFu instance methods" do
|
20
|
+
instance_modules = klass.included_modules
|
21
|
+
assert instance_modules.include?(Technoweenie::AttachmentFu::InstanceMethods),
|
22
|
+
"#{klass} doesn't define AttachmentFu instance methods"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Woulda
|
2
|
+
module EnumerationsMixin
|
3
|
+
module Macros
|
4
|
+
def should_act_as_enumerated(options = {})
|
5
|
+
klass = described_type
|
6
|
+
|
7
|
+
should_have_db_columns :name
|
8
|
+
|
9
|
+
should "define Enumerated macro methods" do
|
10
|
+
class_modules = (class << klass; included_modules; end)
|
11
|
+
assert class_modules.include?(ActiveRecord::Acts::Enumerated::MacroMethods), "#{klass} doesn't define Enumerated macro methods"
|
12
|
+
end
|
13
|
+
|
14
|
+
should "define Enumerated class methods" do
|
15
|
+
class_modules = (class << klass; included_modules; end)
|
16
|
+
assert class_modules.include?(ActiveRecord::Acts::Enumerated::ClassMethods), "#{klass} doesn't define Enumerated class methods"
|
17
|
+
end
|
18
|
+
|
19
|
+
should "define Enumerated instance methods" do
|
20
|
+
instance_modules = klass.included_modules
|
21
|
+
assert instance_modules.include?(ActiveRecord::Acts::Enumerated::InstanceMethods), "#{klass} doesn't define Enumerated instance methods"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Woulda
|
2
|
+
module Paperclip
|
3
|
+
module Macros
|
4
|
+
# Original source: http://giantrobots.thoughtbot.com/2008/6/3/testing-paperclip-with-shoulda
|
5
|
+
def should_have_attached_file(attachment)
|
6
|
+
klass = self.name.gsub(/Test$/, '').constantize
|
7
|
+
|
8
|
+
context "To support a paperclip attachment named #{attachment}, #{klass}" do
|
9
|
+
should_have_db_column("#{attachment}_file_name", :type => :string)
|
10
|
+
should_have_db_column("#{attachment}_content_type", :type => :string)
|
11
|
+
should_have_db_column("#{attachment}_file_size", :type => :integer)
|
12
|
+
end
|
13
|
+
|
14
|
+
should "have a paperclip attachment named ##{attachment}" do
|
15
|
+
assert klass.new.respond_to?(attachment.to_sym),
|
16
|
+
"@#{klass.name.underscore} doesn't have a paperclip field named #{attachment}"
|
17
|
+
assert_equal ::Paperclip::Attachment, klass.new.send(attachment.to_sym).class
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# Copyright (c) 2008 Mathieu Martin
|
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.
|
21
|
+
|
22
|
+
# TODO
|
23
|
+
# - nest contexts/should differently so the message verifications don't clobber each other.
|
24
|
+
# Put exactly same message in last few tests for an example.
|
25
|
+
|
26
|
+
module Woulda
|
27
|
+
module ShouldRaise
|
28
|
+
module Macros
|
29
|
+
# Make sure a block raises an exception.
|
30
|
+
# Call with optional arguments :instance_of/:kind_of and :message
|
31
|
+
# If :instance_of or :kind_of is specified, assert on the given type.
|
32
|
+
# Otherwise only assert that an exception is raised.
|
33
|
+
# Note: The shorthand should_raise(LoadError) is equivalent to should_raise(:instance_of => LoadError)
|
34
|
+
# If :message is specified, will assert that exception.message =~ :message.
|
35
|
+
#
|
36
|
+
# Examples:
|
37
|
+
# should_raise {a block}
|
38
|
+
# should_raise(LoadError) {a block}
|
39
|
+
# should_raise(:instance_of => LoadError) {a block}
|
40
|
+
# should_raise(:kind_of => LoadError) {a block}
|
41
|
+
# should_raise(:message => "no such file to load") {a block}
|
42
|
+
# should_raise(:message => /load/) {a block}
|
43
|
+
# should_raise(LoadError, :message => /load/) {a block}
|
44
|
+
# should_raise(:kind_of => LoadError, :message => /load/) {a block}
|
45
|
+
# should_raise(:instance_of => LoadError, :message => /load/) {a block}
|
46
|
+
def should_raise(*args, &block)
|
47
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
48
|
+
|
49
|
+
if args.first.is_a?(Class)
|
50
|
+
type = args.first
|
51
|
+
exact = true
|
52
|
+
else
|
53
|
+
type = opts[:instance_of] || opts[:kind_of]
|
54
|
+
exact = !!opts[:instance_of]
|
55
|
+
end
|
56
|
+
message = opts[:message]
|
57
|
+
|
58
|
+
# Make sure we don't have a false sense of security and bork if incorrect options are supplied.
|
59
|
+
[:message, :instance_of, :kind_of].each { |acceptable_arg| opts.delete(acceptable_arg) }
|
60
|
+
raise ArgumentError, "Unknown parameter(s): #{opts.keys.inspect}. Only :message, :instance_of and :kind_of are supported." if opts.size > 0
|
61
|
+
|
62
|
+
context "block #{block.inspect}" do # To avoid dupe test names. Any other ideas?
|
63
|
+
should_string = "raise an exception"
|
64
|
+
should_string += " %s type #{type.inspect}" % (exact ? 'of' : 'descending from') if type
|
65
|
+
|
66
|
+
should should_string do
|
67
|
+
begin
|
68
|
+
instance_eval &block
|
69
|
+
rescue Exception => ex
|
70
|
+
@raised_exception = ex
|
71
|
+
end
|
72
|
+
if @raised_exception && type
|
73
|
+
if exact
|
74
|
+
assert_instance_of type, @raised_exception
|
75
|
+
else
|
76
|
+
assert_kind_of type, @raised_exception
|
77
|
+
end
|
78
|
+
else
|
79
|
+
assert @raised_exception, "The block was expected to raise an exception, but didn't"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
if message
|
85
|
+
context "raising an exception" do
|
86
|
+
setup do
|
87
|
+
begin
|
88
|
+
instance_eval &block
|
89
|
+
rescue Exception => ex
|
90
|
+
@raised_exception = ex
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
should "contain a message that matches #{message.inspect}" do
|
95
|
+
assert_match message, @raised_exception.message
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Woulda
|
2
|
+
module WillPaginate
|
3
|
+
module Macros
|
4
|
+
def should_have_per_page(count)
|
5
|
+
klass = self.name.gsub(/Test$/, '').constantize
|
6
|
+
context "#{klass}" do
|
7
|
+
should "respond to per_page" do
|
8
|
+
assert klass.respond_to?(:per_page), "#{klass} does not respond to :per_page"
|
9
|
+
end
|
10
|
+
|
11
|
+
should "have #{count} per page" do
|
12
|
+
assert_equal count, klass.per_page
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/woulda.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
woulda_dir = File.expand_path(File.dirname(__FILE__)) + '/woulda'
|
2
|
+
|
3
|
+
# Standalone Macros
|
4
|
+
require "#{woulda_dir}/should_raise"
|
5
|
+
|
6
|
+
# Macros for gems and plugins
|
7
|
+
require "#{woulda_dir}/acts_as_ferret" if defined? ActsAsFerret
|
8
|
+
require "#{woulda_dir}/acts_as_list" if defined? ActiveRecord::Acts::List
|
9
|
+
require "#{woulda_dir}/acts_as_paranoid" if defined? Caboose::Acts::Paranoid
|
10
|
+
require "#{woulda_dir}/acts_as_taggable_on_steroids" if defined? ActiveRecord::Acts::Taggable
|
11
|
+
require "#{woulda_dir}/attachment_fu" if defined? Technoweenie::AttachmentFu
|
12
|
+
require "#{woulda_dir}/enumerations_mixin" if defined? ActiveRecord::Acts::Enumerated
|
13
|
+
require "#{woulda_dir}/paperclip" if defined? Paperclip
|
14
|
+
require "#{woulda_dir}/will_paginate" if defined? WillPaginate
|
15
|
+
require "#{woulda_dir}/acts_as_solr" if defined? ActsAsSolr
|
16
|
+
require "#{woulda_dir}/acts_as_state_machine" if defined? ScottBarron::Acts::StateMachine
|
17
|
+
require "#{woulda_dir}/acts_as_xapian" if defined? ActsAsXapian
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'woulda'
|
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: svenaas-woulda
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sean Hussey
|
8
|
+
- Josh Nichols
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2010-01-16 00:00:00 -05:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: thoughtbot-shoulda
|
18
|
+
type: :runtime
|
19
|
+
version_requirement:
|
20
|
+
version_requirements: !ruby/object:Gem::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 2.10.2
|
25
|
+
version:
|
26
|
+
description: |
|
27
|
+
Testing is love. Especially when done with "Shoulda":http://thoughtbot.com/projects/shoulda. Shoulda makes testing your Rails app pretty easy.
|
28
|
+
|
29
|
+
There are tons of Rails plugins and gems out there. It should be easy to test your Rails app that uses these as well. That kind of support doesn't really belong in Shoulda itself, though.
|
30
|
+
|
31
|
+
That's where Woulda comes in.
|
32
|
+
|
33
|
+
email:
|
34
|
+
- sean@seanhussey.com
|
35
|
+
- josh@technicalpickles.com
|
36
|
+
executables: []
|
37
|
+
|
38
|
+
extensions: []
|
39
|
+
|
40
|
+
extra_rdoc_files: []
|
41
|
+
|
42
|
+
files:
|
43
|
+
- LICENSE
|
44
|
+
- Rakefile
|
45
|
+
- README.textile
|
46
|
+
- VERSION.yml
|
47
|
+
- shoulda_macros/woulda_macros.rb
|
48
|
+
- lib/woulda/acts_as_ferret/macros.rb
|
49
|
+
- lib/woulda/acts_as_ferret.rb
|
50
|
+
- lib/woulda/acts_as_list/macros.rb
|
51
|
+
- lib/woulda/acts_as_list.rb
|
52
|
+
- lib/woulda/acts_as_paranoid/macros.rb
|
53
|
+
- lib/woulda/acts_as_paranoid.rb
|
54
|
+
- lib/woulda/acts_as_solr/macros.rb
|
55
|
+
- lib/woulda/acts_as_solr.rb
|
56
|
+
- lib/woulda/acts_as_state_machine/macros_new.rb
|
57
|
+
- lib/woulda/acts_as_state_machine/macros_old.rb
|
58
|
+
- lib/woulda/acts_as_state_machine.rb
|
59
|
+
- lib/woulda/acts_as_taggable_on_steroids/macros.rb
|
60
|
+
- lib/woulda/acts_as_taggable_on_steroids.rb
|
61
|
+
- lib/woulda/acts_as_xapian/macros.rb
|
62
|
+
- lib/woulda/acts_as_xapian.rb
|
63
|
+
- lib/woulda/attachment_fu/macros.rb
|
64
|
+
- lib/woulda/attachment_fu.rb
|
65
|
+
- lib/woulda/enumerations_mixin/macros.rb
|
66
|
+
- lib/woulda/enumerations_mixin.rb
|
67
|
+
- lib/woulda/paperclip/macros.rb
|
68
|
+
- lib/woulda/paperclip.rb
|
69
|
+
- lib/woulda/should_raise/macros.rb
|
70
|
+
- lib/woulda/should_raise.rb
|
71
|
+
- lib/woulda/will_paginate/macros.rb
|
72
|
+
- lib/woulda/will_paginate.rb
|
73
|
+
- lib/woulda.rb
|
74
|
+
has_rdoc: true
|
75
|
+
homepage: http://github.com/seanhussey/woulda
|
76
|
+
licenses: []
|
77
|
+
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options:
|
80
|
+
- --inline-source
|
81
|
+
- --charset=UTF-8
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: "0"
|
89
|
+
version:
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: "0"
|
95
|
+
version:
|
96
|
+
requirements: []
|
97
|
+
|
98
|
+
rubyforge_project: woulda
|
99
|
+
rubygems_version: 1.3.5
|
100
|
+
signing_key:
|
101
|
+
specification_version: 2
|
102
|
+
summary: woulda is a home for shoulda macros that don't belong in the main shoulda library
|
103
|
+
test_files: []
|
104
|
+
|