Roman2K-rails-test-serving 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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