rotuka-shoulda-gem 0.0.1
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/Manifest.txt +7 -0
- data/README.txt +69 -0
- data/Rakefile +100 -0
- data/bin/convert_file_to_shoulda +40 -0
- data/lib/proc_extensions.rb +14 -0
- data/lib/shoulda.rb +239 -0
- data/test/test_shoulda.rb +234 -0
- metadata +62 -0
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
Shoulda
|
2
|
+
by Tammer Saleh, Thoughtbot, Inc.
|
3
|
+
http://thoughtbot.com/projects/shoulda
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
The Shoulda gem makes it easy to write elegant, understandable, and maintainable tests. Shoulda consists of test macros, assertions, and helpers added on to the Test::Unit framework. It's fully compatible with your existing tests, and requires no retooling to use. Should also comes with a complimentary Rails plugin, available here - http://thoughtbot.com/projects/shoulda
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
* wrap your tests in nested context blocks to keep them readable and dry
|
12
|
+
* write test names in english, not with_a_bunch_of_underscores
|
13
|
+
* fully compatible with your existing Test::Unit tests
|
14
|
+
* makes writing test macros simple as pie
|
15
|
+
|
16
|
+
== SYNOPSIS:
|
17
|
+
|
18
|
+
class UserTest << Test::Unit
|
19
|
+
context "A User instance" do
|
20
|
+
setup do
|
21
|
+
@user = User.find(:first)
|
22
|
+
end
|
23
|
+
|
24
|
+
should "return its full name" do
|
25
|
+
assert_equal 'John Doe', @user.full_name
|
26
|
+
end
|
27
|
+
|
28
|
+
context "with a profile" do
|
29
|
+
setup do
|
30
|
+
@user.profile = Profile.find(:first)
|
31
|
+
end
|
32
|
+
|
33
|
+
should "return true when sent #has_profile?" do
|
34
|
+
assert @user.has_profile?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
== REQUIREMENTS:
|
41
|
+
|
42
|
+
* Test::Unit
|
43
|
+
|
44
|
+
== INSTALL:
|
45
|
+
|
46
|
+
* sudo gem install shoulda
|
47
|
+
|
48
|
+
== LICENSE:
|
49
|
+
|
50
|
+
Copyright (c) 2007 Tammer Saleh, Thoughtbot, Inc.
|
51
|
+
|
52
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
53
|
+
a copy of this software and associated documentation files (the
|
54
|
+
'Software'), to deal in the Software without restriction, including
|
55
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
56
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
57
|
+
permit persons to whom the Software is furnished to do so, subject to
|
58
|
+
the following conditions:
|
59
|
+
|
60
|
+
The above copyright notice and this permission notice shall be
|
61
|
+
included in all copies or substantial portions of the Software.
|
62
|
+
|
63
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
64
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
65
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
66
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
67
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
68
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
69
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
require 'rubyforge'
|
7
|
+
|
8
|
+
require File.join(File.dirname(__FILE__), 'lib', 'shoulda')
|
9
|
+
|
10
|
+
def paragraphs_of(path, *paragraphs)
|
11
|
+
File.read(path).delete("\r").split(/\n\n+/).values_at(*paragraphs)
|
12
|
+
end
|
13
|
+
|
14
|
+
name = "Shoulda"
|
15
|
+
summary = 'Testing library built on top of Test::Unit'
|
16
|
+
author = 'Tammer Saleh'
|
17
|
+
email = 'tsaleh@thoughtbot.com'
|
18
|
+
version = Thoughtbot::Shoulda::VERSION
|
19
|
+
description = paragraphs_of('README.txt', 2..5).join("\n\n")
|
20
|
+
rubyforge_project = 'shoulda'
|
21
|
+
bindir = "bin"
|
22
|
+
|
23
|
+
desc 'Update documentation on website'
|
24
|
+
task :sync_docs => 'rdoc' do
|
25
|
+
`rsync -ave ssh doc/ tsaleh@rubyforge.org:/var/www/gforge-projects/#{rubyforge_project}`
|
26
|
+
end
|
27
|
+
|
28
|
+
desc 'Package and upload the release to rubyforge.'
|
29
|
+
task :release => [:test, :sync_docs, :package] do |t|
|
30
|
+
puts "Releasing #{name} v#{version} to Rubyforge"
|
31
|
+
pkg = "pkg/#{name}-#{version}"
|
32
|
+
|
33
|
+
rf = RubyForge.new
|
34
|
+
|
35
|
+
c = rf.userconfig
|
36
|
+
c["release_notes"] = description if description
|
37
|
+
# c["release_changes"] = changes if changes
|
38
|
+
c["preformatted"] = true
|
39
|
+
|
40
|
+
puts " Logging in..."
|
41
|
+
rf.login
|
42
|
+
|
43
|
+
files = ["#{pkg}.tgz", "#{pkg}.gem"]
|
44
|
+
|
45
|
+
puts " Uploading..."
|
46
|
+
rf.add_release rubyforge_project, name, version, *files
|
47
|
+
end
|
48
|
+
|
49
|
+
desc 'Default: run tests.'
|
50
|
+
task :default => ['test']
|
51
|
+
|
52
|
+
Dir['tasks/*.rake'].each do |f|
|
53
|
+
load f
|
54
|
+
end
|
55
|
+
|
56
|
+
spec = Gem::Specification.new do |s|
|
57
|
+
s.name = name
|
58
|
+
s.summary = summary
|
59
|
+
s.author = author
|
60
|
+
s.email = email
|
61
|
+
s.version = version
|
62
|
+
s.rubyforge_project = rubyforge_project
|
63
|
+
s.bindir = bindir
|
64
|
+
s.description = description
|
65
|
+
|
66
|
+
url = paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
|
67
|
+
s.homepage = Array(url).first
|
68
|
+
s.files = File.read("Manifest.txt").delete("\r").split(/\n/)
|
69
|
+
s.executables = s.files.grep(/^bin/) { |f| File.basename(f) }
|
70
|
+
|
71
|
+
dirs = Dir['{lib,ext}']
|
72
|
+
s.require_paths = dirs unless dirs.empty?
|
73
|
+
|
74
|
+
s.rdoc_options = ['--main', 'README.txt']
|
75
|
+
s.extra_rdoc_files = s.files.grep(/txt$/)
|
76
|
+
s.has_rdoc = true
|
77
|
+
|
78
|
+
s.test_files = Dir[*['test/**/test_*.rb']]
|
79
|
+
end
|
80
|
+
|
81
|
+
Rake::GemPackageTask.new spec do |pkg|
|
82
|
+
pkg.need_tar = true
|
83
|
+
end
|
84
|
+
|
85
|
+
Rake::TestTask.new do |t|
|
86
|
+
t.libs << 'lib'
|
87
|
+
t.pattern = 'test/**/test_*.rb'
|
88
|
+
t.verbose = false
|
89
|
+
end
|
90
|
+
|
91
|
+
Rake::RDocTask.new { |rdoc|
|
92
|
+
rdoc.rdoc_dir = 'doc'
|
93
|
+
rdoc.title = "Shoulda -- Making tests easy on the fingers and eyes"
|
94
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
95
|
+
rdoc.template = "#{ENV['template']}.rb" if ENV['template']
|
96
|
+
rdoc.rdoc_files.include('README.txt', 'lib/**/*.rb')
|
97
|
+
}
|
98
|
+
|
99
|
+
|
100
|
+
# vim: syntax=Ruby
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
def usage(msg = nil)
|
5
|
+
puts "Error: #{msg}" if msg
|
6
|
+
puts if msg
|
7
|
+
puts "Usage: #{File.basename(__FILE__)} normal_test_file.rb"
|
8
|
+
puts
|
9
|
+
puts "Will convert an existing test file with names like "
|
10
|
+
puts
|
11
|
+
puts " def test_should_do_stuff"
|
12
|
+
puts " ..."
|
13
|
+
puts " end"
|
14
|
+
puts
|
15
|
+
puts "to one using the new syntax: "
|
16
|
+
puts
|
17
|
+
puts " should \"be super cool\" do"
|
18
|
+
puts " ..."
|
19
|
+
puts " end"
|
20
|
+
puts
|
21
|
+
puts "A copy of the old file will be left under /tmp/ in case this script just seriously screws up"
|
22
|
+
puts
|
23
|
+
exit (msg ? 2 : 0)
|
24
|
+
end
|
25
|
+
|
26
|
+
usage("Wrong number of arguments.") unless ARGV.size == 1
|
27
|
+
usage("This system doesn't have a /tmp directory. wtf?") unless File.directory?('/tmp')
|
28
|
+
|
29
|
+
file = ARGV.shift
|
30
|
+
tmpfile = "/tmp/#{File.basename(file)}"
|
31
|
+
usage("File '#{file}' doesn't exist") unless File.exists?(file)
|
32
|
+
|
33
|
+
FileUtils.cp(file, tmpfile)
|
34
|
+
contents = File.read(tmpfile)
|
35
|
+
contents.gsub!(/def test_should_(.*)\s*$/, 'should "\1" do')
|
36
|
+
contents.gsub!(/def test_(.*)\s*$/, 'should "RENAME ME: test \1" do')
|
37
|
+
contents.gsub!(/should ".*" do$/) {|line| line.tr!('_', ' ')}
|
38
|
+
File.open(file, 'w') { |f| f.write(contents) }
|
39
|
+
|
40
|
+
puts "File '#{file}' has been converted to 'should' syntax. Old version has been stored in '#{tmpfile}'"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Stolen straight from ActiveSupport
|
2
|
+
|
3
|
+
class Proc #:nodoc:
|
4
|
+
def bind(object)
|
5
|
+
block, time = self, Time.now
|
6
|
+
(class << object; self end).class_eval do
|
7
|
+
method_name = "__bind_#{time.to_i}_#{time.usec}"
|
8
|
+
define_method(method_name, &block)
|
9
|
+
method = instance_method(method_name)
|
10
|
+
remove_method(method_name)
|
11
|
+
method
|
12
|
+
end.bind(object)
|
13
|
+
end
|
14
|
+
end
|
data/lib/shoulda.rb
ADDED
@@ -0,0 +1,239 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'proc_extensions')
|
2
|
+
|
3
|
+
module Thoughtbot
|
4
|
+
module Shoulda
|
5
|
+
class << self
|
6
|
+
attr_accessor :current_context
|
7
|
+
end
|
8
|
+
|
9
|
+
VERSION = '1.1.1'
|
10
|
+
|
11
|
+
# = Should statements
|
12
|
+
#
|
13
|
+
# Should statements are just syntactic sugar over normal Test::Unit test methods. A should block
|
14
|
+
# contains all the normal code and assertions you're used to seeing, with the added benefit that
|
15
|
+
# they can be wrapped inside context blocks (see below).
|
16
|
+
#
|
17
|
+
# == Example:
|
18
|
+
#
|
19
|
+
# class UserTest << Test::Unit::TestCase
|
20
|
+
#
|
21
|
+
# def setup
|
22
|
+
# @user = User.new("John", "Doe")
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# should "return its full name"
|
26
|
+
# assert_equal 'John Doe', @user.full_name
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# ...will produce the following test:
|
32
|
+
# * <tt>"test: User should return its full name. "</tt>
|
33
|
+
#
|
34
|
+
# Note: The part before <tt>should</tt> in the test name is gleamed from the name of the Test::Unit class.
|
35
|
+
|
36
|
+
def should(name, &blk)
|
37
|
+
if Shoulda.current_context
|
38
|
+
Shoulda.current_context.should(name, &blk)
|
39
|
+
else
|
40
|
+
context_name = self.name.gsub(/Test/, "")
|
41
|
+
context = Thoughtbot::Shoulda::Context.new(context_name, self) do
|
42
|
+
should(name, &blk)
|
43
|
+
end
|
44
|
+
context.build
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Just like should, but never runs, and instead prints an 'X' in the Test::Unit output.
|
49
|
+
def should_eventually(name, &blk)
|
50
|
+
context_name = self.name.gsub(/Test/, "")
|
51
|
+
context = Thoughtbot::Shoulda::Context.new(context_name, self) do
|
52
|
+
should_eventually(name, &blk)
|
53
|
+
end
|
54
|
+
context.build
|
55
|
+
end
|
56
|
+
|
57
|
+
# = Contexts
|
58
|
+
#
|
59
|
+
# A context block groups should statements under a common set of setup/teardown methods.
|
60
|
+
# Context blocks can be arbitrarily nested, and can do wonders for improving the maintainability
|
61
|
+
# and readability of your test code.
|
62
|
+
#
|
63
|
+
# A context block can contain setup, should, should_eventually, and teardown blocks.
|
64
|
+
#
|
65
|
+
# class UserTest << Test::Unit::TestCase
|
66
|
+
# context "A User instance" do
|
67
|
+
# setup do
|
68
|
+
# @user = User.find(:first)
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
# should "return its full name"
|
72
|
+
# assert_equal 'John Doe', @user.full_name
|
73
|
+
# end
|
74
|
+
# end
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# This code will produce the method <tt>"test: A User instance should return its full name. "</tt>.
|
78
|
+
#
|
79
|
+
# Contexts may be nested. Nested contexts run their setup blocks from out to in before each
|
80
|
+
# should statement. They then run their teardown blocks from in to out after each should statement.
|
81
|
+
#
|
82
|
+
# class UserTest << Test::Unit::TestCase
|
83
|
+
# context "A User instance" do
|
84
|
+
# setup do
|
85
|
+
# @user = User.find(:first)
|
86
|
+
# end
|
87
|
+
#
|
88
|
+
# should "return its full name"
|
89
|
+
# assert_equal 'John Doe', @user.full_name
|
90
|
+
# end
|
91
|
+
#
|
92
|
+
# context "with a profile" do
|
93
|
+
# setup do
|
94
|
+
# @user.profile = Profile.find(:first)
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# should "return true when sent :has_profile?"
|
98
|
+
# assert @user.has_profile?
|
99
|
+
# end
|
100
|
+
# end
|
101
|
+
# end
|
102
|
+
# end
|
103
|
+
#
|
104
|
+
# This code will produce the following methods
|
105
|
+
# * <tt>"test: A User instance should return its full name. "</tt>
|
106
|
+
# * <tt>"test: A User instance with a profile should return true when sent :has_profile?. "</tt>
|
107
|
+
#
|
108
|
+
# <b>Just like should statements, a context block can exist next to normal <tt>def test_the_old_way; end</tt>
|
109
|
+
# tests</b>. This means you do not have to fully commit to the context/should syntax in a test file.
|
110
|
+
|
111
|
+
def context(name, &blk)
|
112
|
+
if Shoulda.current_context
|
113
|
+
Shoulda.current_context.context(name, &blk)
|
114
|
+
else
|
115
|
+
context = Thoughtbot::Shoulda::Context.new(name, self, &blk)
|
116
|
+
context.build
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
class Context # :nodoc:
|
121
|
+
|
122
|
+
attr_accessor :name # my name
|
123
|
+
attr_accessor :parent # may be another context, or the original test::unit class.
|
124
|
+
attr_accessor :subcontexts # array of contexts nested under myself
|
125
|
+
attr_accessor :setup_block # block given via a setup method
|
126
|
+
attr_accessor :teardown_block # block given via a teardown method
|
127
|
+
attr_accessor :shoulds # array of hashes representing the should statements
|
128
|
+
attr_accessor :should_eventuallys # array of hashes representing the should eventually statements
|
129
|
+
|
130
|
+
def initialize(name, parent, &blk)
|
131
|
+
Shoulda.current_context = self
|
132
|
+
self.name = name
|
133
|
+
self.parent = parent
|
134
|
+
self.setup_block = nil
|
135
|
+
self.teardown_block = nil
|
136
|
+
self.shoulds = []
|
137
|
+
self.should_eventuallys = []
|
138
|
+
self.subcontexts = []
|
139
|
+
|
140
|
+
blk.bind(self).call
|
141
|
+
Shoulda.current_context = nil
|
142
|
+
end
|
143
|
+
|
144
|
+
def context(name, &blk)
|
145
|
+
subcontexts << Context.new(name, self, &blk)
|
146
|
+
Shoulda.current_context = self
|
147
|
+
end
|
148
|
+
|
149
|
+
def setup(&blk)
|
150
|
+
self.setup_block = blk
|
151
|
+
end
|
152
|
+
|
153
|
+
def teardown(&blk)
|
154
|
+
self.teardown_block = blk
|
155
|
+
end
|
156
|
+
|
157
|
+
def should(name, &blk)
|
158
|
+
self.shoulds << { :name => name, :block => blk }
|
159
|
+
end
|
160
|
+
|
161
|
+
def should_eventually(name, &blk)
|
162
|
+
self.should_eventuallys << { :name => name, :block => blk }
|
163
|
+
end
|
164
|
+
|
165
|
+
def full_name
|
166
|
+
parent_name = parent.full_name if am_subcontext?
|
167
|
+
return [parent_name, name].join(" ").strip
|
168
|
+
end
|
169
|
+
|
170
|
+
def am_subcontext?
|
171
|
+
parent.is_a?(self.class) # my parent is the same class as myself.
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_unit_class
|
175
|
+
am_subcontext? ? parent.test_unit_class : parent
|
176
|
+
end
|
177
|
+
|
178
|
+
def create_test_from_should_hash(should)
|
179
|
+
test_name = ["test:", full_name, "should", "#{should[:name]}. "].flatten.join(' ').to_sym
|
180
|
+
|
181
|
+
if test_unit_class.instance_methods.include?(test_name.to_s)
|
182
|
+
warn " * WARNING: '#{test_name}' is already defined"
|
183
|
+
end
|
184
|
+
|
185
|
+
context = self
|
186
|
+
test_unit_class.send(:define_method, test_name) do |*args|
|
187
|
+
begin
|
188
|
+
context.run_all_setup_blocks(self)
|
189
|
+
should[:block].bind(self).call
|
190
|
+
ensure
|
191
|
+
context.run_all_teardown_blocks(self)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def run_all_setup_blocks(binding)
|
197
|
+
self.parent.run_all_setup_blocks(binding) if am_subcontext?
|
198
|
+
setup_block.bind(binding).call if setup_block
|
199
|
+
end
|
200
|
+
|
201
|
+
def run_all_teardown_blocks(binding)
|
202
|
+
teardown_block.bind(binding).call if teardown_block
|
203
|
+
self.parent.run_all_teardown_blocks(binding) if am_subcontext?
|
204
|
+
end
|
205
|
+
|
206
|
+
def print_should_eventuallys
|
207
|
+
should_eventuallys.each do |should|
|
208
|
+
test_name = [full_name, "should", "#{should[:name]}. "].flatten.join(' ')
|
209
|
+
puts " * DEFERRED: " + test_name
|
210
|
+
end
|
211
|
+
subcontexts.each { |context| context.print_should_eventuallys }
|
212
|
+
end
|
213
|
+
|
214
|
+
def build
|
215
|
+
shoulds.each do |should|
|
216
|
+
create_test_from_should_hash(should)
|
217
|
+
end
|
218
|
+
|
219
|
+
subcontexts.each { |context| context.build }
|
220
|
+
|
221
|
+
print_should_eventuallys
|
222
|
+
end
|
223
|
+
|
224
|
+
def method_missing(method, *args, &blk)
|
225
|
+
test_unit_class.send(method, *args, &blk)
|
226
|
+
end
|
227
|
+
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
module Test # :nodoc: all
|
233
|
+
module Unit
|
234
|
+
class TestCase
|
235
|
+
extend Thoughtbot::Shoulda
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
@@ -0,0 +1,234 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'shoulda')
|
3
|
+
require 'rubygems'
|
4
|
+
require 'mocha'
|
5
|
+
|
6
|
+
class TestShoulda < Test::Unit::TestCase # :nodoc:
|
7
|
+
|
8
|
+
should "be able to define a should statement outside of a context" do
|
9
|
+
assert true
|
10
|
+
end
|
11
|
+
|
12
|
+
should "see the name of my class as TestShoulda" do
|
13
|
+
assert_equal "TestShoulda", self.class.name
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.should_see_class_methods
|
17
|
+
should "be able to see class methods" do
|
18
|
+
assert true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.should_see_a_context_block_like_a_Test_Unit_class
|
23
|
+
should "see a context block as a Test::Unit class" do
|
24
|
+
assert_equal "TestShoulda", self.class.name
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.should_see_blah
|
29
|
+
should "see @blah through a macro" do
|
30
|
+
assert @blah
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.should_not_see_blah
|
35
|
+
should "not see @blah through a macro" do
|
36
|
+
assert_nil @blah
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.should_be_able_to_make_context_macros(prefix = nil)
|
41
|
+
context "a macro" do
|
42
|
+
should "have the tests named correctly" do
|
43
|
+
assert_match(/^test: #{prefix}a macro should have the tests named correctly/, self.to_s)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "Context" do
|
49
|
+
|
50
|
+
should_see_class_methods
|
51
|
+
should_see_a_context_block_like_a_Test_Unit_class
|
52
|
+
should_be_able_to_make_context_macros("Context ")
|
53
|
+
|
54
|
+
should "not define @blah" do
|
55
|
+
assert ! self.instance_variables.include?("@blah")
|
56
|
+
end
|
57
|
+
|
58
|
+
should_not_see_blah
|
59
|
+
|
60
|
+
should "be able to define a should statement" do
|
61
|
+
assert true
|
62
|
+
end
|
63
|
+
|
64
|
+
should "see the name of my class as TestShoulda" do
|
65
|
+
assert_equal "TestShoulda", self.class.name
|
66
|
+
end
|
67
|
+
|
68
|
+
context "with a subcontext" do
|
69
|
+
should_be_able_to_make_context_macros("Context with a subcontext ")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "Context with setup block" do
|
74
|
+
setup do
|
75
|
+
@blah = "blah"
|
76
|
+
end
|
77
|
+
|
78
|
+
should "have @blah == 'blah'" do
|
79
|
+
assert_equal "blah", @blah
|
80
|
+
end
|
81
|
+
should_see_blah
|
82
|
+
|
83
|
+
should "have name set right" do
|
84
|
+
assert_match(/^test: Context with setup block/, self.to_s)
|
85
|
+
end
|
86
|
+
|
87
|
+
context "and a subcontext" do
|
88
|
+
setup do
|
89
|
+
@blah = "#{@blah} twice"
|
90
|
+
end
|
91
|
+
|
92
|
+
should "be named correctly" do
|
93
|
+
assert_match(/^test: Context with setup block and a subcontext should be named correctly/, self.to_s)
|
94
|
+
end
|
95
|
+
|
96
|
+
should "run the setup methods in order" do
|
97
|
+
assert_equal @blah, "blah twice"
|
98
|
+
end
|
99
|
+
should_see_blah
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "Another context with setup block" do
|
104
|
+
setup do
|
105
|
+
@blah = "foo"
|
106
|
+
end
|
107
|
+
|
108
|
+
should "have @blah == 'foo'" do
|
109
|
+
assert_equal "foo", @blah
|
110
|
+
end
|
111
|
+
|
112
|
+
should "have name set right" do
|
113
|
+
assert_match(/^test: Another context with setup block/, self.to_s)
|
114
|
+
end
|
115
|
+
should_see_blah
|
116
|
+
end
|
117
|
+
|
118
|
+
should_eventually "pass, since it's a should_eventually" do
|
119
|
+
flunk "what?"
|
120
|
+
end
|
121
|
+
|
122
|
+
# Context creation and naming
|
123
|
+
|
124
|
+
def test_should_create_a_new_context
|
125
|
+
assert_nothing_raised do
|
126
|
+
Thoughtbot::Shoulda::Context.new("context name", self) do; end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_should_create_a_nested_context
|
131
|
+
assert_nothing_raised do
|
132
|
+
parent = Thoughtbot::Shoulda::Context.new("Parent", self) do; end
|
133
|
+
child = Thoughtbot::Shoulda::Context.new("Child", parent) do; end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_should_name_a_contexts_correctly
|
138
|
+
parent = Thoughtbot::Shoulda::Context.new("Parent", self) do; end
|
139
|
+
child = Thoughtbot::Shoulda::Context.new("Child", parent) do; end
|
140
|
+
grandchild = Thoughtbot::Shoulda::Context.new("GrandChild", child) do; end
|
141
|
+
|
142
|
+
assert_equal "Parent", parent.full_name
|
143
|
+
assert_equal "Parent Child", child.full_name
|
144
|
+
assert_equal "Parent Child GrandChild", grandchild.full_name
|
145
|
+
end
|
146
|
+
|
147
|
+
# Should statements
|
148
|
+
|
149
|
+
def test_should_have_should_hashes_when_given_should_statements
|
150
|
+
context = Thoughtbot::Shoulda::Context.new("name", self) do
|
151
|
+
should "be good" do; end
|
152
|
+
should "another" do; end
|
153
|
+
end
|
154
|
+
|
155
|
+
names = context.shoulds.map {|s| s[:name]}
|
156
|
+
assert_equal ["another", "be good"], names.sort
|
157
|
+
end
|
158
|
+
|
159
|
+
# setup and teardown
|
160
|
+
|
161
|
+
def test_should_capture_setup_and_teardown_blocks
|
162
|
+
context = Thoughtbot::Shoulda::Context.new("name", self) do
|
163
|
+
setup do; "setup"; end
|
164
|
+
teardown do; "teardown"; end
|
165
|
+
end
|
166
|
+
|
167
|
+
assert_equal "setup", context.setup_block.call
|
168
|
+
assert_equal "teardown", context.teardown_block.call
|
169
|
+
end
|
170
|
+
|
171
|
+
# building
|
172
|
+
|
173
|
+
def test_should_create_shoulda_test_for_each_should_on_build
|
174
|
+
context = Thoughtbot::Shoulda::Context.new("name", self) do
|
175
|
+
should "one" do; end
|
176
|
+
should "two" do; end
|
177
|
+
end
|
178
|
+
context.expects(:create_test_from_should_hash).with(has_entry(:name => "one"))
|
179
|
+
context.expects(:create_test_from_should_hash).with(has_entry(:name => "two"))
|
180
|
+
context.build
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_should_create_test_methods_on_build
|
184
|
+
tu_class = Test::Unit::TestCase
|
185
|
+
context = Thoughtbot::Shoulda::Context.new("A Context", tu_class) do
|
186
|
+
should "define the test" do; end
|
187
|
+
end
|
188
|
+
|
189
|
+
tu_class.expects(:define_method).with(:"test: A Context should define the test. ")
|
190
|
+
context.build
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_should_create_test_methods_on_build_when_subcontext
|
194
|
+
tu_class = Test::Unit::TestCase
|
195
|
+
context = Thoughtbot::Shoulda::Context.new("A Context", tu_class) do
|
196
|
+
context "with a child" do
|
197
|
+
should "define the test" do; end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
tu_class.expects(:define_method).with(:"test: A Context with a child should define the test. ")
|
202
|
+
context.build
|
203
|
+
end
|
204
|
+
|
205
|
+
# Test::Unit integration
|
206
|
+
|
207
|
+
def test_should_create_a_new_context_and_build_it_on_Test_Unit_context
|
208
|
+
c = mock("context")
|
209
|
+
c.expects(:build)
|
210
|
+
Thoughtbot::Shoulda::Context.expects(:new).with("foo", kind_of(Class)).returns(c)
|
211
|
+
self.class.context "foo" do; end
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_should_create_a_one_off_context_and_build_it_on_Test_Unit_should
|
215
|
+
s = mock("test")
|
216
|
+
Thoughtbot::Shoulda::Context.any_instance.expects(:should).with("rock").returns(s)
|
217
|
+
Thoughtbot::Shoulda::Context.any_instance.expects(:build)
|
218
|
+
self.class.should "rock" do; end
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_should_define_a_test_on_should
|
222
|
+
s = mock("test")
|
223
|
+
Thoughtbot::Shoulda::Context.any_instance.expects(:should).with("rock").returns(s)
|
224
|
+
Thoughtbot::Shoulda::Context.any_instance.expects(:build)
|
225
|
+
self.class.should "rock" do; end
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_should_create_a_one_off_context_and_build_it_on_Test_Unit_should_eventually
|
229
|
+
s = mock("test")
|
230
|
+
Thoughtbot::Shoulda::Context.any_instance.expects(:should_eventually).with("rock").returns(s)
|
231
|
+
Thoughtbot::Shoulda::Context.any_instance.expects(:build)
|
232
|
+
self.class.should_eventually "rock" do; end
|
233
|
+
end
|
234
|
+
end
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rotuka-shoulda-gem
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Thoughtbot
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-07-08 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: "The Shoulda Rails plugin makes it easy to write elegant, understandable, and maintainable tests. Shoulda consists of test macros, assertions, and helpers added on to the Test::Unit framework. It\xE2\x80\x99s fully compatible with your existing tests, and requires no retooling to use."
|
17
|
+
email:
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- Manifest.txt
|
24
|
+
- README.txt
|
25
|
+
files:
|
26
|
+
- .gemspec
|
27
|
+
- Manifest.txt
|
28
|
+
- Rakefile
|
29
|
+
- README.txt
|
30
|
+
- bin/convert_file_to_shoulda
|
31
|
+
- lib/proc_extensions.rb
|
32
|
+
- lib/shoulda.rb
|
33
|
+
- test/test_shoulda.rb
|
34
|
+
has_rdoc: true
|
35
|
+
homepage: http://github.com/thoughtbot/shoulda-gem
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options:
|
38
|
+
- --main
|
39
|
+
- README.txt
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
version:
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
version:
|
54
|
+
requirements: []
|
55
|
+
|
56
|
+
rubyforge_project:
|
57
|
+
rubygems_version: 1.2.0
|
58
|
+
signing_key:
|
59
|
+
specification_version: 2
|
60
|
+
summary: Testing made easier on the fingers and the eyes
|
61
|
+
test_files:
|
62
|
+
- test/test_shoulda.rb
|