deep_test 1.1.4 → 1.2.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/CHANGELOG +15 -5
- data/README +149 -5
- data/Rakefile +131 -11
- data/bin/deep_test +15 -0
- data/lib/deep_test.rb +62 -4
- data/lib/deep_test/database/mysql_setup_listener.rb +109 -0
- data/lib/deep_test/database/setup_listener.rb +116 -0
- data/lib/deep_test/distributed/dispatch_controller.rb +53 -0
- data/lib/deep_test/distributed/drb_client_connection_info.rb +15 -0
- data/lib/deep_test/distributed/filename_resolver.rb +40 -0
- data/lib/deep_test/distributed/master_test_server.rb +52 -0
- data/lib/deep_test/distributed/multi_test_server_proxy.rb +44 -0
- data/lib/deep_test/distributed/null_work_unit.rb +12 -0
- data/lib/deep_test/distributed/remote_worker_client.rb +54 -0
- data/lib/deep_test/distributed/remote_worker_server.rb +82 -0
- data/lib/deep_test/distributed/rsync.rb +37 -0
- data/lib/deep_test/distributed/show_status.rhtml +41 -0
- data/lib/deep_test/distributed/test_server.rb +78 -0
- data/lib/deep_test/distributed/test_server_status.rb +9 -0
- data/lib/deep_test/distributed/test_server_workers.rb +24 -0
- data/lib/deep_test/distributed/throughput_runner.rb +42 -0
- data/lib/deep_test/distributed/throughput_statistics.rb +26 -0
- data/lib/deep_test/distributed/throughput_worker_client.rb +19 -0
- data/lib/deep_test/extensions/drb_extension.rb +34 -0
- data/lib/deep_test/extensions/object_extension.rb +8 -0
- data/lib/deep_test/listener_list.rb +17 -0
- data/lib/deep_test/local_workers.rb +55 -0
- data/lib/deep_test/logger.rb +10 -2
- data/lib/deep_test/marshallable_exception_wrapper.rb +44 -0
- data/lib/deep_test/metrics/gatherer.rb +67 -0
- data/lib/deep_test/metrics/queue_lock_wait_time_measurement.rb +133 -0
- data/lib/deep_test/null_worker_listener.rb +50 -0
- data/lib/deep_test/option.rb +60 -0
- data/lib/deep_test/options.rb +61 -24
- data/lib/deep_test/process_orchestrator.rb +31 -78
- data/lib/deep_test/rake_tasks.rb +3 -0
- data/lib/deep_test/result_reader.rb +36 -0
- data/lib/deep_test/rspec_detector.rb +15 -8
- data/lib/deep_test/server.rb +68 -4
- data/lib/deep_test/spec.rb +1 -0
- data/lib/deep_test/spec/extensions/example_group_methods.rb +37 -11
- data/lib/deep_test/spec/extensions/example_methods.rb +46 -0
- data/lib/deep_test/spec/extensions/options.rb +35 -3
- data/lib/deep_test/spec/runner.rb +19 -10
- data/lib/deep_test/spec/work_result.rb +12 -9
- data/lib/deep_test/spec/work_unit.rb +12 -7
- data/lib/deep_test/test.rb +1 -1
- data/lib/deep_test/test/extensions/error.rb +7 -7
- data/lib/deep_test/test/runner.rb +1 -6
- data/lib/deep_test/test/supervised_test_suite.rb +19 -16
- data/lib/deep_test/test/work_result.rb +34 -0
- data/lib/deep_test/test/work_unit.rb +6 -2
- data/lib/deep_test/test_task.rb +15 -35
- data/lib/deep_test/ui/console.rb +76 -0
- data/lib/deep_test/ui/null.rb +17 -0
- data/lib/deep_test/warlock.rb +92 -17
- data/lib/deep_test/worker.rb +38 -2
- data/script/internal/run_test_suite.rb +7 -0
- data/script/public/master_test_server.rb +24 -0
- data/script/public/test_server.rb +18 -0
- data/script/public/test_throughput.rb +29 -0
- data/test/deep_test/database/mysql_setup_listener_test.rb +14 -0
- data/test/deep_test/distributed/dispatch_controller_test.rb +209 -0
- data/test/deep_test/distributed/drb_client_connection_info_test.rb +42 -0
- data/test/deep_test/distributed/filename_resolver_test.rb +52 -0
- data/test/deep_test/distributed/master_test_server_test.rb +32 -0
- data/test/deep_test/distributed/multi_test_server_proxy_test.rb +96 -0
- data/test/deep_test/distributed/remote_worker_client_test.rb +180 -0
- data/test/deep_test/distributed/remote_worker_server_test.rb +99 -0
- data/test/deep_test/distributed/rsync_test.rb +67 -0
- data/test/deep_test/distributed/test_server_test.rb +94 -0
- data/test/deep_test/distributed/test_server_workers_test.rb +26 -0
- data/test/deep_test/distributed/throughput_runner_test.rb +68 -0
- data/test/deep_test/distributed/throughput_worker_client_test.rb +28 -0
- data/test/deep_test/listener_list_test.rb +20 -0
- data/test/deep_test/local_workers_test.rb +22 -0
- data/test/{logger_test.rb → deep_test/logger_test.rb} +2 -2
- data/test/deep_test/marshallable_exception_wrapper_test.rb +44 -0
- data/test/deep_test/metrics/gatherer_test.rb +66 -0
- data/test/deep_test/process_orchestrator_test.rb +11 -0
- data/test/deep_test/result_reader_test.rb +128 -0
- data/test/deep_test/server_test.rb +58 -0
- data/test/deep_test/test/extensions/error_test.rb +40 -0
- data/test/deep_test/test/supervised_test_suite_test.rb +19 -29
- data/test/deep_test/test/work_result_test.rb +81 -0
- data/test/deep_test/test/work_unit_test.rb +15 -4
- data/test/deep_test/test_task_test.rb +10 -0
- data/test/deep_test/ui/console_test.rb +9 -0
- data/test/deep_test/warlock_test.rb +17 -0
- data/test/deep_test/worker_test.rb +32 -0
- data/test/simple_test_blackboard.rb +2 -1
- data/test/test_helper.rb +1 -0
- metadata +117 -59
- data/lib/deep_test/rinda_blackboard.rb +0 -26
- data/lib/deep_test/test/extensions/test_result.rb +0 -17
- data/lib/deep_test/tuple_space_factory.rb +0 -12
- data/script/run_test_suite.rb +0 -5
- data/test/deep_test/rinda_blackboard_test.rb +0 -15
- data/test/deep_test/test/extensions/test_result_test.rb +0 -71
data/lib/deep_test/options.rb
CHANGED
|
@@ -1,33 +1,25 @@
|
|
|
1
1
|
module DeepTest
|
|
2
2
|
class Options
|
|
3
|
-
class Option
|
|
4
|
-
attr_reader :name, :default
|
|
5
|
-
|
|
6
|
-
def initialize(name, conversion, default)
|
|
7
|
-
@name, @conversion, @default = name, conversion, default
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def from_command_line(command_line)
|
|
11
|
-
command_line =~ /--#{name} (\S+)(\s|$)/
|
|
12
|
-
$1.send(@conversion) if $1
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def to_command_line(value)
|
|
16
|
-
"--#{name} #{value}" if value && value != default
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
3
|
unless defined?(VALID_OPTIONS)
|
|
21
4
|
VALID_OPTIONS = [
|
|
22
|
-
Option.new(:
|
|
23
|
-
Option.new(:
|
|
24
|
-
Option.new(:
|
|
25
|
-
Option.new(:
|
|
26
|
-
Option.new(:
|
|
5
|
+
Option.new(:distributed_server, Option::String, nil),
|
|
6
|
+
Option.new(:number_of_workers, Option::Integer, 2),
|
|
7
|
+
Option.new(:metrics_file, Option::String, nil),
|
|
8
|
+
Option.new(:pattern, Option::String, nil),
|
|
9
|
+
Option.new(:server_port, Option::Integer, 6969),
|
|
10
|
+
Option.new(:sync_options, Option::Hash, {}),
|
|
11
|
+
Option.new(:timeout_in_seconds, Option::Integer, 30),
|
|
12
|
+
Option.new(:ui, Option::String, "DeepTest::UI::Console"),
|
|
13
|
+
Option.new(:worker_listener, Option::String, "DeepTest::NullWorkerListener"),
|
|
27
14
|
]
|
|
28
15
|
end
|
|
29
16
|
|
|
30
17
|
attr_accessor *VALID_OPTIONS.map {|o| o.name}
|
|
18
|
+
|
|
19
|
+
def ui=(value)
|
|
20
|
+
@ui = value.to_s
|
|
21
|
+
end
|
|
22
|
+
|
|
31
23
|
def worker_listener=(value)
|
|
32
24
|
@worker_listener = value.to_s
|
|
33
25
|
end
|
|
@@ -41,14 +33,35 @@ module DeepTest
|
|
|
41
33
|
end
|
|
42
34
|
|
|
43
35
|
def initialize(hash)
|
|
36
|
+
@origin_hostname = Socket.gethostname
|
|
44
37
|
check_option_keys(hash)
|
|
45
38
|
VALID_OPTIONS.each do |option|
|
|
46
39
|
send("#{option.name}=", hash[option.name] || option.default)
|
|
47
40
|
end
|
|
48
41
|
end
|
|
49
42
|
|
|
50
|
-
def
|
|
51
|
-
|
|
43
|
+
def gathering_metrics?
|
|
44
|
+
!@metrics_file.nil?
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def new_listener_list
|
|
48
|
+
listeners = worker_listener.split(',').map do |listener|
|
|
49
|
+
eval(listener).new
|
|
50
|
+
end
|
|
51
|
+
ListenerList.new(listeners)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def origin_hostname
|
|
55
|
+
(Socket.gethostname == @origin_hostname) ? 'localhost' : @origin_hostname
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Don't store UI instances in the options instance, which will
|
|
59
|
+
# need to be dumped over DRb. UI instances may not be dumpable
|
|
60
|
+
# and we don't want to have to start yet another DRb Server
|
|
61
|
+
#
|
|
62
|
+
UI_INSTANCES = {} unless defined?(UI_INSTANCES)
|
|
63
|
+
def ui_instance
|
|
64
|
+
UI_INSTANCES[self] ||= eval(ui).new(self)
|
|
52
65
|
end
|
|
53
66
|
|
|
54
67
|
def to_command_line
|
|
@@ -60,6 +73,30 @@ module DeepTest
|
|
|
60
73
|
command_line.compact.join(' ')
|
|
61
74
|
end
|
|
62
75
|
|
|
76
|
+
def mirror_path(base)
|
|
77
|
+
raise "No source directory specified in sync_options" unless sync_options[:source]
|
|
78
|
+
relative_mirror_path = origin_hostname + sync_options[:source].gsub('/','_')
|
|
79
|
+
"#{base}/#{relative_mirror_path}"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def new_workers
|
|
83
|
+
if distributed_server.nil?
|
|
84
|
+
LocalWorkers.new self
|
|
85
|
+
else
|
|
86
|
+
begin
|
|
87
|
+
server = Distributed::TestServer.connect(self)
|
|
88
|
+
Distributed::RemoteWorkerClient.new(self, server, LocalWorkers.new(self))
|
|
89
|
+
rescue => e
|
|
90
|
+
ui_instance.distributed_failover_to_local("connect", e)
|
|
91
|
+
LocalWorkers.new self
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def server
|
|
97
|
+
Server.remote_reference(origin_hostname, server_port)
|
|
98
|
+
end
|
|
99
|
+
|
|
63
100
|
protected
|
|
64
101
|
|
|
65
102
|
def check_option_keys(hash)
|
|
@@ -1,96 +1,49 @@
|
|
|
1
1
|
module DeepTest
|
|
2
2
|
class ProcessOrchestrator
|
|
3
|
-
def self.run(options, runner)
|
|
4
|
-
new(options, runner).run
|
|
3
|
+
def self.run(options, workers, runner)
|
|
4
|
+
new(options, workers, runner).run
|
|
5
5
|
end
|
|
6
6
|
|
|
7
|
-
def initialize(options, runner)
|
|
7
|
+
def initialize(options, workers, runner)
|
|
8
8
|
@options = options
|
|
9
9
|
@runner = runner
|
|
10
|
+
@workers = workers
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
def run
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def exit_process
|
|
26
|
-
Kernel.exit($?.success? ? 0 : 1)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def start_all_workers
|
|
30
|
-
each_worker do |worker_num|
|
|
31
|
-
start_worker(worker_num) do
|
|
32
|
-
reseed_random_numbers
|
|
33
|
-
reconnect_to_database
|
|
34
|
-
worker = DeepTest::Worker.new(worker_num,
|
|
35
|
-
RindaBlackboard.new(@options),
|
|
36
|
-
@options.new_worker_listener)
|
|
37
|
-
worker.run
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def reconnect_to_database
|
|
43
|
-
ActiveRecord::Base.connection.reconnect! if defined?(ActiveRecord::Base)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def start_worker(worker_num, &blk)
|
|
47
|
-
@warlock.start("worker #{worker_num}", &blk)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def reseed_random_numbers
|
|
51
|
-
srand
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def wait_for_loader_to_be_done
|
|
55
|
-
Process.wait(@loader_pid)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def start_warlock_server
|
|
59
|
-
server_ready = false
|
|
60
|
-
previous_trap = Signal.trap('USR2') {server_ready = true}
|
|
61
|
-
|
|
62
|
-
pid = Process.pid
|
|
63
|
-
@warlock.start("server") do
|
|
64
|
-
DeepTest::Server.start(@options) do
|
|
65
|
-
Process.kill('USR2', pid)
|
|
13
|
+
def run(exit_when_done = true)
|
|
14
|
+
passed = false
|
|
15
|
+
|
|
16
|
+
begin
|
|
17
|
+
server = Server.start(@options)
|
|
18
|
+
@options.new_listener_list.before_starting_workers
|
|
19
|
+
@workers.start_all
|
|
20
|
+
begin
|
|
21
|
+
DeepTest.logger.debug "Loader Starting (#{$$})"
|
|
22
|
+
passed = @runner.process_work_units
|
|
23
|
+
ensure
|
|
24
|
+
shutdown(server)
|
|
66
25
|
end
|
|
26
|
+
ensure
|
|
27
|
+
DeepTest.logger.debug "ProcessOrchestrator: Stopping Server"
|
|
28
|
+
Server.stop
|
|
67
29
|
end
|
|
68
30
|
|
|
69
|
-
|
|
70
|
-
ensure
|
|
71
|
-
Signal.trap('USR2', previous_trap)
|
|
31
|
+
Kernel.exit(passed ? 0 : 1) if exit_when_done
|
|
72
32
|
end
|
|
73
33
|
|
|
74
|
-
def
|
|
75
|
-
|
|
76
|
-
|
|
34
|
+
def shutdown(server)
|
|
35
|
+
DeepTest.logger.debug "ProcessOrchestrator: Shutting Down"
|
|
36
|
+
server.done_with_work
|
|
77
37
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
def start_loader
|
|
88
|
-
@loader_pid = fork do
|
|
89
|
-
DeepTest.logger.debug "Loader Starting (#{$$})"
|
|
90
|
-
passed = @runner.process_work_units
|
|
91
|
-
exit(passed ? 0 : 1)
|
|
38
|
+
first_exception = $!
|
|
39
|
+
begin
|
|
40
|
+
DeepTest.logger.debug "ProcessOrchestrator: Stopping Workers"
|
|
41
|
+
@workers.stop_all
|
|
42
|
+
rescue DRb::DRbConnError
|
|
43
|
+
# Workers must have already stopped
|
|
44
|
+
rescue Exception => e
|
|
45
|
+
raise first_exception || e
|
|
92
46
|
end
|
|
93
47
|
end
|
|
94
|
-
|
|
95
48
|
end
|
|
96
49
|
end
|
data/lib/deep_test/rake_tasks.rb
CHANGED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module DeepTest
|
|
2
|
+
class ResultReader
|
|
3
|
+
def initialize(blackboard)
|
|
4
|
+
@blackboard = blackboard
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def read(original_work_units_by_id)
|
|
8
|
+
work_units_by_id = original_work_units_by_id.dup
|
|
9
|
+
errors = 0
|
|
10
|
+
|
|
11
|
+
begin
|
|
12
|
+
until errors == work_units_by_id.size
|
|
13
|
+
Thread.pass
|
|
14
|
+
result = @blackboard.take_result
|
|
15
|
+
next if result.nil?
|
|
16
|
+
|
|
17
|
+
if Worker::Error === result
|
|
18
|
+
puts result
|
|
19
|
+
errors += 1
|
|
20
|
+
else
|
|
21
|
+
if result.respond_to?(:output) && (output = result.output)
|
|
22
|
+
print output
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
work_unit = work_units_by_id.delete(result.identifier)
|
|
26
|
+
yield [work_unit, result]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
rescue Server::ResultOverdueError
|
|
30
|
+
DeepTest.logger.error("Results are overdue from server, ending run")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
work_units_by_id
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
module DeepTest
|
|
2
2
|
class RSpecDetector
|
|
3
3
|
def self.if_rspec_available
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
else
|
|
4
|
+
require "rubygems"
|
|
5
|
+
# requiring 'spec' directly blows up unit-record
|
|
6
|
+
require "spec/version"
|
|
7
|
+
if defined?(::Spec)
|
|
8
|
+
if ::Spec::VERSION::MAJOR >= 1 &&
|
|
9
|
+
::Spec::VERSION::MINOR >= 1 &&
|
|
10
|
+
::Spec::VERSION::TINY >= 3
|
|
12
11
|
yield
|
|
12
|
+
else
|
|
13
|
+
require 'spec/rake/spectask'
|
|
14
|
+
::Spec::Rake::SpecTask.class_eval do
|
|
15
|
+
def deep_test(options)
|
|
16
|
+
raise "* DeepTest RSpec support requires RSpec 1.1.3 or greater"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
13
19
|
end
|
|
14
20
|
end
|
|
21
|
+
rescue LoadError, Gem::LoadError
|
|
15
22
|
end
|
|
16
23
|
end
|
|
17
24
|
end
|
data/lib/deep_test/server.rb
CHANGED
|
@@ -1,11 +1,75 @@
|
|
|
1
1
|
module DeepTest
|
|
2
2
|
class Server
|
|
3
3
|
def self.start(options)
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
server = new(options)
|
|
5
|
+
DRb.start_service("druby://0.0.0.0:#{options.server_port}", server)
|
|
6
6
|
DeepTest.logger.info "Started DeepTest service at #{DRb.uri}"
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
server
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.stop
|
|
11
|
+
DRb.stop_service
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.remote_reference(address, port)
|
|
15
|
+
DRb.start_service
|
|
16
|
+
blackboard = DRbObject.new_with_uri("druby://#{address}:#{port}")
|
|
17
|
+
DeepTest.logger.debug "Connecting to DeepTest server at #{blackboard.__drburi}"
|
|
18
|
+
blackboard
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def initialize(options)
|
|
22
|
+
@options = options
|
|
23
|
+
@work_queue = Queue.new
|
|
24
|
+
@result_queue = Queue.new
|
|
25
|
+
|
|
26
|
+
if Metrics::Gatherer.enabled?
|
|
27
|
+
require File.dirname(__FILE__) + "/metrics/queue_lock_wait_time_measurement"
|
|
28
|
+
@work_queue.extend Metrics::QueueLockWaitTimeMeasurement
|
|
29
|
+
@result_queue.extend Metrics::QueueLockWaitTimeMeasurement
|
|
30
|
+
Metrics::Gatherer.section("server queue lock wait times") do |s|
|
|
31
|
+
s.measurement("work queue total pop wait time", @work_queue.total_pop_time)
|
|
32
|
+
s.measurement("work queue total push wait time", @work_queue.total_push_time)
|
|
33
|
+
s.measurement("result queue total pop wait time", @result_queue.total_pop_time)
|
|
34
|
+
s.measurement("result queue total push wait time", @result_queue.total_push_time)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def done_with_work
|
|
40
|
+
@done_with_work = true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def take_result
|
|
44
|
+
Timeout.timeout(@options.timeout_in_seconds, ResultOverdueError) do
|
|
45
|
+
@result_queue.pop
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def take_work
|
|
50
|
+
raise NoWorkUnitsRemainingError if @done_with_work
|
|
51
|
+
|
|
52
|
+
@work_queue.pop(true)
|
|
53
|
+
rescue ThreadError => e
|
|
54
|
+
if e.message == "queue empty"
|
|
55
|
+
raise NoWorkUnitsAvailableError
|
|
56
|
+
else
|
|
57
|
+
raise
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def write_result(result)
|
|
62
|
+
@result_queue.push result
|
|
63
|
+
nil
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def write_work(work_unit)
|
|
67
|
+
@work_queue.push work_unit
|
|
68
|
+
nil
|
|
9
69
|
end
|
|
70
|
+
|
|
71
|
+
class NoWorkUnitsAvailableError < StandardError; end
|
|
72
|
+
class NoWorkUnitsRemainingError < StandardError; end
|
|
73
|
+
class ResultOverdueError < StandardError; end
|
|
10
74
|
end
|
|
11
75
|
end
|
data/lib/deep_test/spec.rb
CHANGED
|
@@ -3,6 +3,7 @@ require 'spec/example/example_group_methods'
|
|
|
3
3
|
require 'spec/rake/spectask'
|
|
4
4
|
|
|
5
5
|
require File.dirname(__FILE__) + "/spec/extensions/example_group_methods"
|
|
6
|
+
require File.dirname(__FILE__) + "/spec/extensions/example_methods"
|
|
6
7
|
require File.dirname(__FILE__) + "/spec/extensions/spec_task"
|
|
7
8
|
require File.dirname(__FILE__) + "/spec/extensions/options"
|
|
8
9
|
require File.dirname(__FILE__) + "/spec/extensions/reporter"
|
|
@@ -1,38 +1,64 @@
|
|
|
1
1
|
module Spec
|
|
2
2
|
module Example
|
|
3
3
|
module ExampleGroupMethods
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
class << self
|
|
5
|
+
def assign_instance_method_to_constant(proposed_constant)
|
|
6
|
+
method_sym = proposed_constant.to_s.downcase
|
|
7
|
+
|
|
8
|
+
unless const_defined?(proposed_constant)
|
|
9
|
+
const_set(proposed_constant, instance_method(method_sym))
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private :assign_instance_method_to_constant
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
assign_instance_method_to_constant :PREPEND_BEFORE
|
|
17
|
+
assign_instance_method_to_constant :APPEND_BEFORE
|
|
18
|
+
assign_instance_method_to_constant :PREPEND_AFTER
|
|
19
|
+
assign_instance_method_to_constant :APPEND_AFTER
|
|
8
20
|
|
|
9
21
|
def prepend_before(*args, &block)
|
|
10
22
|
check_filter_args(args)
|
|
11
|
-
|
|
23
|
+
call_regular_instance_method :prepend_before, *args, &block
|
|
12
24
|
end
|
|
13
25
|
|
|
14
26
|
def append_before(*args, &block)
|
|
15
27
|
check_filter_args(args)
|
|
16
|
-
|
|
28
|
+
call_regular_instance_method :append_before, *args, &block
|
|
17
29
|
end
|
|
30
|
+
|
|
18
31
|
alias_method :before, :append_before
|
|
19
32
|
|
|
20
33
|
def prepend_after(*args, &block)
|
|
21
34
|
check_filter_args(args)
|
|
22
|
-
|
|
35
|
+
call_regular_instance_method :prepend_after, *args, &block
|
|
23
36
|
end
|
|
24
37
|
|
|
25
38
|
def append_after(*args, &block)
|
|
26
39
|
check_filter_args(args)
|
|
27
|
-
|
|
40
|
+
call_regular_instance_method :append_after, *args, &block
|
|
28
41
|
end
|
|
42
|
+
|
|
29
43
|
alias_method :after, :append_after
|
|
30
44
|
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
DeepTestAllBlockWarning =
|
|
48
|
+
"Warning: DeepTest will run before(:all) and after(:all) blocks for *every* test that is run. To remove this warning either convert all before/after blocks to each blocks or set $show_deep_test_all_block_warning to false" unless defined?(DeepTestAllBlockWarning)
|
|
49
|
+
|
|
50
|
+
$show_deep_test_all_block_warning = true
|
|
51
|
+
|
|
31
52
|
def check_filter_args(args)
|
|
32
|
-
|
|
53
|
+
if args.first == :all && $show_deep_test_all_block_warning
|
|
54
|
+
$show_deep_test_all_block_warning = false
|
|
55
|
+
$stderr.puts DeepTestAllBlockWarning
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def call_regular_instance_method(sym, *args, &block)
|
|
60
|
+
ExampleGroupMethods.const_get(sym.to_s.upcase).bind(self).call(*args, &block)
|
|
33
61
|
end
|
|
34
|
-
|
|
35
|
-
class BeforeAfterAllNotSupportedByDeepTestError < StandardError; end
|
|
36
62
|
end
|
|
37
63
|
end
|
|
38
64
|
end
|