Roman2K-rails-test-serving 0.1.0
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/LICENSE +19 -0
- data/README.rdoc +28 -0
- data/Rakefile +11 -0
- data/lib/rails_test_serving.rb +352 -0
- data/rails-test-serving.gemspec +68 -0
- data/test/rails_test_serving_test.rb +211 -0
- metadata +65 -0
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2008 Roman Le Négrate
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
Tired of waiting 10 seconds before your tests run? RailsTestServing can make them run almost instantly. Details in the {introduction article}[http://roman.flucti.com/a-test-server-for-rails-applications].
|
2
|
+
|
3
|
+
== Quick usage instructions
|
4
|
+
|
5
|
+
1. Insert the following lines at the very top of <tt>test/test_helper.rb</tt>:
|
6
|
+
require 'rails_test_serving'
|
7
|
+
RailsTestServing.boot
|
8
|
+
|
9
|
+
2. Start the server:
|
10
|
+
cd <project-dir>
|
11
|
+
ruby test/test_helper.rb --serve
|
12
|
+
|
13
|
+
3. Run tests as you usually do:
|
14
|
+
ruby test/unit/account_test.rb
|
15
|
+
ruby test/unit/account_test.rb -n /balance/
|
16
|
+
As a consequence, they work in RubyMate too (⌘R in TextMate).
|
17
|
+
|
18
|
+
<b>Note:</b> if the server is not started, tests fall back to running the usual way.
|
19
|
+
|
20
|
+
== Caveats
|
21
|
+
|
22
|
+
* There might exist some quirks: search for "TODO" in the source. I can bear them
|
23
|
+
but contributions are welcome.
|
24
|
+
* Some unit tests are left to be written.
|
25
|
+
|
26
|
+
== Credits
|
27
|
+
|
28
|
+
Written by {Roman Le Négrate}[http://roman.flucti.com] ({contact}[mailto:roman.lenegrate@gmail.com]). Released under the MIT license: see the +LICENSE+ file.
|
data/Rakefile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'echoe'
|
2
|
+
|
3
|
+
Echoe.new('rails-test-serving', '0.1.1') do |p|
|
4
|
+
p.description = "Makes unit tests of a Rails application run instantly"
|
5
|
+
p.url = "https://github.com/Roman2K/rails-test-serving"
|
6
|
+
p.author = "Roman Le Négrate"
|
7
|
+
p.email = "roman.lenegrate@gmail.com"
|
8
|
+
p.ignore_pattern = "*.gemspec"
|
9
|
+
p.development_dependencies = []
|
10
|
+
p.rdoc_options = %w(--main README.rdoc --inline-source --line-numbers --charset UTF-8)
|
11
|
+
end
|
@@ -0,0 +1,352 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'drb/unix'
|
4
|
+
require 'stringio'
|
5
|
+
require 'benchmark'
|
6
|
+
|
7
|
+
module RailsTestServing
|
8
|
+
class InvalidArgumentPattern < ArgumentError
|
9
|
+
end
|
10
|
+
class ServerUnavailable < StandardError
|
11
|
+
end
|
12
|
+
|
13
|
+
SERVICE_URI = "drbunix:tmp/sockets/test_server.sock"
|
14
|
+
|
15
|
+
def self.boot(argv=ARGV)
|
16
|
+
if argv.delete('--serve')
|
17
|
+
Server.start
|
18
|
+
elsif !argv.delete('--local')
|
19
|
+
Client.run_tests
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module ConstantManagement
|
24
|
+
extend self
|
25
|
+
|
26
|
+
def legit?(const)
|
27
|
+
!const.to_s.empty? && constantize(const) == const
|
28
|
+
end
|
29
|
+
|
30
|
+
def constantize(name)
|
31
|
+
eval("#{name} if defined? #{name}", TOPLEVEL_BINDING)
|
32
|
+
end
|
33
|
+
|
34
|
+
def constantize!(name)
|
35
|
+
name.to_s.split('::').inject(Object) { |namespace, short| namespace.const_get(short) }
|
36
|
+
end
|
37
|
+
|
38
|
+
# ActiveSupport's Module#remove_class doesn't behave quite the way I would expect it to.
|
39
|
+
def remove_constants(*names)
|
40
|
+
names.map do |name|
|
41
|
+
namespace, short = name.to_s =~ /^(.+)::(.+?)$/ ? [$1, $2] : ['Object', name]
|
42
|
+
constantize!(namespace).module_eval { remove_const(short) if const_defined?(short) }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def subclasses_of(parent, options={})
|
47
|
+
children = []
|
48
|
+
ObjectSpace.each_object(Class) { |klass| children << klass if klass < parent && (!options[:legit] || legit?(klass)) }
|
49
|
+
children
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
module Client
|
54
|
+
extend self
|
55
|
+
|
56
|
+
# Setting this variable to true inhibits #run_tests.
|
57
|
+
@@disabled = false
|
58
|
+
|
59
|
+
def disable
|
60
|
+
@@disabled = true
|
61
|
+
yield
|
62
|
+
ensure
|
63
|
+
@@disabled = false
|
64
|
+
end
|
65
|
+
|
66
|
+
def tests_on_exit
|
67
|
+
!Test::Unit.run?
|
68
|
+
end
|
69
|
+
|
70
|
+
def tests_on_exit=(yes)
|
71
|
+
Test::Unit.run = !yes
|
72
|
+
end
|
73
|
+
|
74
|
+
def run_tests
|
75
|
+
return if @@disabled
|
76
|
+
run_tests!
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def run_tests!
|
82
|
+
handle_process_lifecycle do
|
83
|
+
server = DRbObject.new_with_uri(SERVICE_URI)
|
84
|
+
begin
|
85
|
+
puts(server.run($0, ARGV))
|
86
|
+
rescue DRb::DRbConnError
|
87
|
+
raise ServerUnavailable
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def handle_process_lifecycle
|
93
|
+
Client.tests_on_exit = false
|
94
|
+
begin
|
95
|
+
yield
|
96
|
+
rescue ServerUnavailable, InvalidArgumentPattern
|
97
|
+
Client.tests_on_exit = true
|
98
|
+
else
|
99
|
+
# TODO exit with a status code reflecting the result of the tests
|
100
|
+
exit 0
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
class Server
|
106
|
+
GUARD = Mutex.new
|
107
|
+
|
108
|
+
def self.start
|
109
|
+
DRb.start_service(SERVICE_URI, Server.new)
|
110
|
+
DRb.thread.join
|
111
|
+
end
|
112
|
+
|
113
|
+
def initialize
|
114
|
+
ENV['RAILS_ENV'] = 'test'
|
115
|
+
enable_dependency_tracking
|
116
|
+
start_cleaner
|
117
|
+
load_framework
|
118
|
+
|
119
|
+
log "** Test server started (##{$$})\n"
|
120
|
+
end
|
121
|
+
|
122
|
+
def run(file, argv)
|
123
|
+
GUARD.synchronize { perform_run(file, argv) }
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def log(message)
|
129
|
+
$stdout.print(message)
|
130
|
+
$stdout.flush
|
131
|
+
end
|
132
|
+
|
133
|
+
def shorten_path(path)
|
134
|
+
shortenable, base = File.expand_path(path), File.expand_path(Dir.pwd)
|
135
|
+
attempt = shortenable.sub(/^#{Regexp.escape base + File::SEPARATOR}/, '')
|
136
|
+
attempt.length < path.length ? attempt : path
|
137
|
+
end
|
138
|
+
|
139
|
+
def enable_dependency_tracking
|
140
|
+
require 'initializer'
|
141
|
+
|
142
|
+
Rails::Configuration.class_eval do
|
143
|
+
unless method_defined? :cache_classes
|
144
|
+
raise "#{self.class} out of sync with current Rails version"
|
145
|
+
end
|
146
|
+
|
147
|
+
def cache_classes
|
148
|
+
false
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def start_cleaner
|
154
|
+
@cleaner = Cleaner.new
|
155
|
+
end
|
156
|
+
|
157
|
+
def load_framework
|
158
|
+
Client.disable { require 'test_helper' }
|
159
|
+
end
|
160
|
+
|
161
|
+
def perform_run(file, argv)
|
162
|
+
sanitize_arguments! file, argv
|
163
|
+
|
164
|
+
log ">> " + [shorten_path(file), *argv].join(' ')
|
165
|
+
|
166
|
+
result = nil
|
167
|
+
elapsed = Benchmark.realtime do
|
168
|
+
result = capture_test_result(file, argv)
|
169
|
+
end
|
170
|
+
log " (%d ms)\n" % (elapsed * 1000)
|
171
|
+
result
|
172
|
+
end
|
173
|
+
|
174
|
+
def sanitize_arguments!(file, argv)
|
175
|
+
if file =~ /^-/
|
176
|
+
# No file was specified for loading, only options. It's the case with
|
177
|
+
# Autotest.
|
178
|
+
raise InvalidArgumentPattern
|
179
|
+
end
|
180
|
+
|
181
|
+
# Filter out the junk that TextMate seems to inject into ARGV when running
|
182
|
+
# focused tests.
|
183
|
+
while a = find_index_by_pattern(argv, /^\[/) and z = find_index_by_pattern(argv[a..-1], /\]$/)
|
184
|
+
argv[a..a+z] = []
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def capture_test_result(file, argv)
|
189
|
+
result = []
|
190
|
+
@cleaner.clean_up_around do
|
191
|
+
result << capture_standard_stream('err') do
|
192
|
+
result << capture_standard_stream('out') do
|
193
|
+
result << capture_testrunner_result do
|
194
|
+
fix_objectspace_collector do
|
195
|
+
Client.disable { load(file) }
|
196
|
+
Test::Unit::AutoRunner.run(false, nil, argv)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
result.reverse.join
|
203
|
+
end
|
204
|
+
|
205
|
+
def capture_standard_stream(name)
|
206
|
+
eval("old, $std#{name} = $std#{name}, StringIO.new")
|
207
|
+
begin
|
208
|
+
yield
|
209
|
+
return eval("$std#{name}").string
|
210
|
+
ensure
|
211
|
+
eval("$std#{name} = old")
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def capture_testrunner_result
|
216
|
+
set_default_testrunner_stream(io = StringIO.new) { yield }
|
217
|
+
io.string
|
218
|
+
end
|
219
|
+
|
220
|
+
# The default output stream of TestRunner is STDOUT which cannot be captured
|
221
|
+
# and, as a consequence, neither can TestRunner output when not instantiated
|
222
|
+
# explicitely. The following method can change the default output stream
|
223
|
+
# argument so that it can be set to a stream that can be captured instead.
|
224
|
+
def set_default_testrunner_stream(io)
|
225
|
+
require 'test/unit/ui/console/testrunner'
|
226
|
+
|
227
|
+
Test::Unit::UI::Console::TestRunner.class_eval do
|
228
|
+
alias_method :old_initialize, :initialize
|
229
|
+
def initialize(suite, output_level, io=Thread.current["test_runner_io"])
|
230
|
+
old_initialize(suite, output_level, io)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
Thread.current["test_runner_io"] = io
|
234
|
+
|
235
|
+
begin
|
236
|
+
return yield
|
237
|
+
ensure
|
238
|
+
Thread.current["test_runner_io"] = nil
|
239
|
+
Test::Unit::UI::Console::TestRunner.class_eval do
|
240
|
+
alias_method :initialize, :old_initialize
|
241
|
+
remove_method :old_initialize
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
# The stock ObjectSpace collector collects every single class that inherits
|
247
|
+
# from Test::Unit, including those which have just been unassigned from
|
248
|
+
# their constant and not yet garbage collected. This method fixes that
|
249
|
+
# behaviour by filtering out these soon-to-be-garbage-collected classes.
|
250
|
+
def fix_objectspace_collector
|
251
|
+
require 'test/unit/collector/objectspace'
|
252
|
+
|
253
|
+
Test::Unit::Collector::ObjectSpace.class_eval do
|
254
|
+
alias_method :old_collect, :collect
|
255
|
+
def collect(name)
|
256
|
+
tests = []
|
257
|
+
ConstantManagement.subclasses_of(Test::Unit::TestCase, :legit => true).each { |klass| add_suite(tests, klass.suite) }
|
258
|
+
suite = Test::Unit::TestSuite.new(name)
|
259
|
+
sort(tests).each { |t| suite << t }
|
260
|
+
suite
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
begin
|
265
|
+
return yield
|
266
|
+
ensure
|
267
|
+
Test::Unit::Collector::ObjectSpace.class_eval do
|
268
|
+
alias_method :collect, :old_collect
|
269
|
+
remove_method :old_collect
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
private
|
275
|
+
|
276
|
+
def find_index_by_pattern(enumerable, pattern)
|
277
|
+
enumerable.each_with_index do |element, index|
|
278
|
+
return index if pattern === element
|
279
|
+
end
|
280
|
+
nil
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
class Cleaner
|
285
|
+
include ConstantManagement
|
286
|
+
|
287
|
+
BREATH = 0.01
|
288
|
+
TESTCASE_CLASS_NAMES = %w( Test::Unit::TestCase
|
289
|
+
ActiveSupport::TestCase
|
290
|
+
ActionView::TestCase
|
291
|
+
ActionController::TestCase
|
292
|
+
ActionController::IntegrationTest
|
293
|
+
ActionMailer::TestCase )
|
294
|
+
|
295
|
+
def initialize
|
296
|
+
start_worker
|
297
|
+
end
|
298
|
+
|
299
|
+
def clean_up_around
|
300
|
+
check_worker_health
|
301
|
+
sleep BREATH while @working
|
302
|
+
begin
|
303
|
+
reload_app
|
304
|
+
yield
|
305
|
+
ensure
|
306
|
+
@working = true
|
307
|
+
sleep BREATH until @worker.stop?
|
308
|
+
@worker.wakeup
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
private
|
313
|
+
|
314
|
+
def start_worker
|
315
|
+
@worker = Thread.new do
|
316
|
+
Thread.abort_on_exception = true
|
317
|
+
loop do
|
318
|
+
Thread.stop
|
319
|
+
begin
|
320
|
+
clean_up_app
|
321
|
+
remove_tests
|
322
|
+
ensure
|
323
|
+
@working = false
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
327
|
+
@working = false
|
328
|
+
end
|
329
|
+
|
330
|
+
def check_worker_health
|
331
|
+
unless @worker.alive?
|
332
|
+
$stderr.puts "cleaning thread died, restarting"
|
333
|
+
start_worker
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
def clean_up_app
|
338
|
+
ActionController::Dispatcher.new.cleanup_application
|
339
|
+
end
|
340
|
+
|
341
|
+
def remove_tests
|
342
|
+
TESTCASE_CLASS_NAMES.each do |name|
|
343
|
+
next unless klass = constantize(name)
|
344
|
+
remove_constants(*subclasses_of(klass).map { |c| c.to_s }.grep(/Test$/) - TESTCASE_CLASS_NAMES)
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
def reload_app
|
349
|
+
ActionController::Dispatcher.new.reload_application
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end unless defined? RailsTestServing
|
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
# Gem::Specification for Rails-test-serving-0.1.0
|
3
|
+
# Originally generated by Echoe
|
4
|
+
|
5
|
+
--- !ruby/object:Gem::Specification
|
6
|
+
name: rails-test-serving
|
7
|
+
version: !ruby/object:Gem::Version
|
8
|
+
version: 0.1.0
|
9
|
+
platform: ruby
|
10
|
+
authors:
|
11
|
+
- "Roman Le N\xC3\xA9grate"
|
12
|
+
autorequire:
|
13
|
+
bindir: bin
|
14
|
+
|
15
|
+
date: 2008-11-16 00:00:00 +01:00
|
16
|
+
default_executable:
|
17
|
+
dependencies: []
|
18
|
+
|
19
|
+
description: Makes unit tests of a Rails application run instantly
|
20
|
+
email: roman.lenegrate@gmail.com
|
21
|
+
executables: []
|
22
|
+
|
23
|
+
extensions: []
|
24
|
+
|
25
|
+
extra_rdoc_files:
|
26
|
+
- lib/rails_test_serving.rb
|
27
|
+
- LICENSE
|
28
|
+
- README.rdoc
|
29
|
+
files:
|
30
|
+
- lib/rails_test_serving.rb
|
31
|
+
- LICENSE
|
32
|
+
- Manifest
|
33
|
+
- rails-test-serving.gemspec
|
34
|
+
- Rakefile
|
35
|
+
- README.rdoc
|
36
|
+
- test/rails_test_serving_test.rb
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: https://github.com/Roman2K/rails-test-serving
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options:
|
41
|
+
- --main
|
42
|
+
- README.rdoc
|
43
|
+
- --inline-source
|
44
|
+
- --line-numbers
|
45
|
+
- --charset
|
46
|
+
- UTF-8
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "1.2"
|
60
|
+
version:
|
61
|
+
requirements: []
|
62
|
+
|
63
|
+
rubyforge_project: rails-test-serving
|
64
|
+
rubygems_version: 1.3.1
|
65
|
+
specification_version: 2
|
66
|
+
summary: Makes unit tests of a Rails application run instantly
|
67
|
+
test_files:
|
68
|
+
- test/rails_test_serving_test.rb
|
@@ -0,0 +1,211 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'mocha'
|
3
|
+
Mocha::Configuration.prevent :stubbing_non_existent_method
|
4
|
+
Mocha::Configuration.warn_when :stubbing_method_unnecessarily
|
5
|
+
|
6
|
+
require 'rails_test_serving'
|
7
|
+
|
8
|
+
class RailsTestServingTest < Test::Unit::TestCase
|
9
|
+
include RailsTestServing
|
10
|
+
|
11
|
+
# class
|
12
|
+
|
13
|
+
def test_boot
|
14
|
+
argv = []
|
15
|
+
Client.expects(:run_tests)
|
16
|
+
RailsTestServing.boot(argv)
|
17
|
+
|
18
|
+
argv = ['--local']
|
19
|
+
Client.expects(:run_tests).never
|
20
|
+
RailsTestServing.boot(argv)
|
21
|
+
assert_equal [], argv
|
22
|
+
|
23
|
+
argv = ["--serve"]
|
24
|
+
Server.expects(:start)
|
25
|
+
RailsTestServing.boot(argv)
|
26
|
+
assert_equal [], argv
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class RailsTestServing::ConstantManagementTest < Test::Unit::TestCase
|
31
|
+
include RailsTestServing::ConstantManagement
|
32
|
+
NS = self
|
33
|
+
|
34
|
+
Foo = :foo
|
35
|
+
NamedFoo = Module.new
|
36
|
+
Namespace = Module.new
|
37
|
+
|
38
|
+
class A; end
|
39
|
+
class B < A; end
|
40
|
+
class C < B; end
|
41
|
+
|
42
|
+
def test_legit
|
43
|
+
assert legit?(NamedFoo)
|
44
|
+
|
45
|
+
assert !legit?("Inexistent")
|
46
|
+
|
47
|
+
fake = stub(:to_s => NamedFoo.to_s)
|
48
|
+
assert_equal NamedFoo.to_s, "#{fake}" # sanity check
|
49
|
+
assert !legit?(fake)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_constantize
|
53
|
+
assert_equal :foo, constantize("#{NS}::Foo")
|
54
|
+
assert_equal nil, constantize("#{NS}::Bar")
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_constantize!
|
58
|
+
assert_equal :foo, constantize!("#{NS}::Foo")
|
59
|
+
assert_raise(NameError) { constantize!("#{NS}::Bar") }
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_remove_constants
|
63
|
+
mod_A = Module.new
|
64
|
+
Namespace.const_set(:A, mod_A)
|
65
|
+
assert eval("defined? #{NS}::Namespace::A") # sanity check
|
66
|
+
|
67
|
+
removed = remove_constants("#{NS}::Namespace::A")
|
68
|
+
assert_equal [mod_A], removed
|
69
|
+
assert !eval("defined? #{NS}::Namespace::A")
|
70
|
+
|
71
|
+
removed = remove_constants("#{NS}::Namespace::A")
|
72
|
+
assert_equal [nil], removed
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_subclasses_of
|
76
|
+
assert_equal [C, B], subclasses_of(A)
|
77
|
+
assert_equal [C], subclasses_of(B)
|
78
|
+
assert_equal [], subclasses_of(C)
|
79
|
+
|
80
|
+
self.stubs(:legit?).with(B).returns true
|
81
|
+
self.stubs(:legit?).with(C).returns false
|
82
|
+
assert_equal [B], subclasses_of(A, :legit => true)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class RailsTestServing::ClientTest < Test::Unit::TestCase
|
87
|
+
C = RailsTestServing::Client
|
88
|
+
|
89
|
+
def test_run_tests
|
90
|
+
C.expects(:run_tests!)
|
91
|
+
C.run_tests
|
92
|
+
|
93
|
+
C.disable do
|
94
|
+
C.expects(:run_tests!).never
|
95
|
+
C.run_tests
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
class RailsTestServing::ServerTest < Test::Unit::TestCase
|
101
|
+
|
102
|
+
# private
|
103
|
+
|
104
|
+
def test_perform_run
|
105
|
+
server = stub_server
|
106
|
+
file, argv = "test.rb", ["-n", "/pat/"]
|
107
|
+
|
108
|
+
server.stubs(:sanitize_arguments!)
|
109
|
+
Benchmark.stubs(:realtime).yields.returns 1
|
110
|
+
|
111
|
+
server.expects(:log).with(">> test.rb -n /pat/").once
|
112
|
+
server.stubs(:capture_test_result).with(file, argv).returns "result"
|
113
|
+
server.expects(:log).with(" (1000 ms)\n").once
|
114
|
+
|
115
|
+
result = server.instance_eval { perform_run(file, argv) }
|
116
|
+
assert_equal "result", result
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_sanitize_arguments
|
120
|
+
server = stub_server
|
121
|
+
sanitize = lambda { |*args| server.instance_eval { sanitize_arguments! *args } }
|
122
|
+
|
123
|
+
# valid
|
124
|
+
file, argv = "test.rb", ["--name=test_create"]
|
125
|
+
sanitize.call file, argv
|
126
|
+
|
127
|
+
assert_equal "test.rb", file
|
128
|
+
assert_equal ["--name=test_create"], argv
|
129
|
+
|
130
|
+
# TextMate junk
|
131
|
+
junk = ["[test_create,", "nil,", "nil]"]
|
132
|
+
|
133
|
+
# a) at the beginning
|
134
|
+
file, argv = "test.rb", junk + ["foo"]
|
135
|
+
sanitize.call file, argv
|
136
|
+
|
137
|
+
assert_equal "test.rb", file
|
138
|
+
assert_equal ["foo"], argv
|
139
|
+
|
140
|
+
# b) in between normal arguments
|
141
|
+
file, argv = "test.rb", ["foo"] + junk + ["bar"]
|
142
|
+
sanitize.call file, argv
|
143
|
+
|
144
|
+
assert_equal "test.rb", file
|
145
|
+
assert_equal ["foo", "bar"], argv
|
146
|
+
|
147
|
+
# invalid arguments
|
148
|
+
assert_raise RailsTestServing::InvalidArgumentPattern do
|
149
|
+
sanitize.call "-e", ["code"]
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_shorten_path
|
154
|
+
server = stub_server
|
155
|
+
Dir.stubs(:pwd).returns '/base'
|
156
|
+
|
157
|
+
assert_equal 'test.rb', server.instance_eval { shorten_path 'test.rb' }
|
158
|
+
assert_equal 'test.rb', server.instance_eval { shorten_path '/base/test.rb' }
|
159
|
+
assert_equal '/other-base/test.rb', server.instance_eval { shorten_path '/other-base/test.rb' }
|
160
|
+
assert_equal '/other-base/test.rb', server.instance_eval { shorten_path '/other-base/././test.rb' }
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_capture_test_result
|
164
|
+
server = stub_server
|
165
|
+
cleaner = server.instance_variable_set(:@cleaner, stub)
|
166
|
+
|
167
|
+
cleaner.stubs(:clean_up_around).yields
|
168
|
+
server.stubs(:capture_standard_stream).with('err').yields.returns "stderr"
|
169
|
+
server.stubs(:capture_standard_stream).with('out').yields.returns "stdout"
|
170
|
+
server.stubs(:capture_testrunner_result).yields.returns "result"
|
171
|
+
server.stubs(:fix_objectspace_collector).yields
|
172
|
+
|
173
|
+
server.stubs(:load).with("file")
|
174
|
+
Test::Unit::AutoRunner.expects(:run).with(false, nil, "argv")
|
175
|
+
|
176
|
+
result = server.instance_eval { capture_test_result("file", "argv") }
|
177
|
+
assert_equal "stderrstdoutresult", result
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_capture_standard_stream
|
181
|
+
server = stub_server
|
182
|
+
assert_equal STDOUT, $stdout # sanity check
|
183
|
+
|
184
|
+
captured = server.instance_eval { capture_standard_stream('out') { print "test" } }
|
185
|
+
|
186
|
+
assert_equal "test", captured
|
187
|
+
assert_equal STDOUT, $stdout
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_capture_testrunner_result
|
191
|
+
server = stub_server
|
192
|
+
|
193
|
+
captured = server.instance_eval do
|
194
|
+
capture_testrunner_result { Thread.current["test_runner_io"].print "test" }
|
195
|
+
end
|
196
|
+
|
197
|
+
assert_equal "test", captured
|
198
|
+
end
|
199
|
+
|
200
|
+
private
|
201
|
+
|
202
|
+
S = RailsTestServing::Server
|
203
|
+
|
204
|
+
def stub_server
|
205
|
+
S.any_instance.stubs(:enable_dependency_tracking)
|
206
|
+
S.any_instance.stubs(:start_cleaner)
|
207
|
+
S.any_instance.stubs(:load_framework)
|
208
|
+
S.any_instance.stubs(:log)
|
209
|
+
S.new
|
210
|
+
end
|
211
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: Roman2K-rails-test-serving
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- "Roman Le N\xC3\xA9grate"
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
date: 2008-11-15 15:00:00 -08:00
|
12
|
+
default_executable:
|
13
|
+
dependencies: []
|
14
|
+
|
15
|
+
description: Makes unit tests of a Rails application run instantly
|
16
|
+
email: roman.lenegrate@gmail.com
|
17
|
+
executables: []
|
18
|
+
|
19
|
+
extensions: []
|
20
|
+
|
21
|
+
extra_rdoc_files:
|
22
|
+
- lib/rails_test_serving.rb
|
23
|
+
- LICENSE
|
24
|
+
- README.rdoc
|
25
|
+
files:
|
26
|
+
- lib/rails_test_serving.rb
|
27
|
+
- LICENSE
|
28
|
+
- Manifest
|
29
|
+
- rails-test-serving.gemspec
|
30
|
+
- Rakefile
|
31
|
+
- README.rdoc
|
32
|
+
- test/rails_test_serving_test.rb
|
33
|
+
has_rdoc: true
|
34
|
+
homepage: https://github.com/Roman2K/rails-test-serving
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options:
|
37
|
+
- --main
|
38
|
+
- README.rdoc
|
39
|
+
- --inline-source
|
40
|
+
- --line-numbers
|
41
|
+
- --charset
|
42
|
+
- UTF-8
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
version:
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "1.2"
|
56
|
+
version:
|
57
|
+
requirements: []
|
58
|
+
|
59
|
+
rubyforge_project: rails-test-serving
|
60
|
+
rubygems_version: 1.2.0
|
61
|
+
signing_key:
|
62
|
+
specification_version: 2
|
63
|
+
summary: Makes unit tests of a Rails application run instantly
|
64
|
+
test_files:
|
65
|
+
- test/rails_test_serving_test.rb
|