rspec_starter 1.5.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +9 -0
- data/.travis.yml +5 -5
- data/CHANGELOG.md +29 -18
- data/README.md +145 -115
- data/exe/rspec_starter +14 -1
- data/lib/rspec_starter.rb +69 -24
- data/lib/rspec_starter/command.rb +59 -0
- data/lib/rspec_starter/command_context.rb +38 -0
- data/lib/rspec_starter/core_ext/string.rb +6 -3
- data/lib/rspec_starter/environment.rb +57 -0
- data/lib/rspec_starter/errors/step_error.rb +9 -0
- data/lib/rspec_starter/errors/step_stopper.rb +9 -0
- data/lib/rspec_starter/help.rb +79 -32
- data/lib/rspec_starter/helpers.rb +74 -0
- data/lib/rspec_starter/{which.rb → helpers/which.rb} +0 -0
- data/lib/rspec_starter/legacy.rb +16 -0
- data/lib/rspec_starter/legacy/help.rb +40 -0
- data/lib/rspec_starter/legacy/legacy_runner.rb +90 -0
- data/lib/rspec_starter/{steps → legacy/steps}/invoke_rspec_step.rb +2 -0
- data/lib/rspec_starter/{steps → legacy/steps}/prepare_database_step.rb +3 -1
- data/lib/rspec_starter/{steps → legacy/steps}/remove_tmp_folder_step.rb +3 -0
- data/lib/rspec_starter/{steps → legacy/steps}/step.rb +0 -0
- data/lib/rspec_starter/{steps → legacy/steps}/verify_xvfb_step.rb +2 -0
- data/lib/rspec_starter/option.rb +84 -0
- data/lib/rspec_starter/options.rb +96 -0
- data/lib/rspec_starter/rspec_starter_task.rb +35 -0
- data/lib/rspec_starter/runner.rb +15 -74
- data/lib/rspec_starter/step.rb +181 -0
- data/lib/rspec_starter/step_context.rb +28 -0
- data/lib/rspec_starter/step_options.rb +20 -0
- data/lib/rspec_starter/task_context.rb +63 -0
- data/lib/rspec_starter/tasks/rebuild_rails_app_database.rb +50 -0
- data/lib/rspec_starter/tasks/remove_tmp_folder.rb +28 -0
- data/lib/rspec_starter/tasks/start_rspec.rb +68 -0
- data/lib/rspec_starter/tasks/verify_display_server.rb +43 -0
- data/lib/rspec_starter/version.rb +1 -1
- data/lib/templates/rails_engine_start_rspec +38 -0
- data/lib/templates/rails_start_rspec +38 -0
- data/lib/templates/start_rspec +20 -5
- data/rspec_starter.gemspec +4 -2
- metadata +63 -14
@@ -0,0 +1,74 @@
|
|
1
|
+
# Helper methods that can be used anywhere in RspecStarter.
|
2
|
+
module RspecStarter
|
3
|
+
def self.helpers
|
4
|
+
@helpers ||= Helpers.new
|
5
|
+
end
|
6
|
+
|
7
|
+
# A class that provides helper methods that can be used anywhere in RspecStarter.
|
8
|
+
class Helpers
|
9
|
+
def class_for_task_name(string_or_symbol)
|
10
|
+
string_or_symbol.to_s.camelize.constantize
|
11
|
+
end
|
12
|
+
|
13
|
+
def project_is_rails_app?
|
14
|
+
@project_is_rails_app ||= File.file?(File.join(Dir.pwd, 'config', 'application.rb'))
|
15
|
+
end
|
16
|
+
|
17
|
+
def project_is_rails_engine?
|
18
|
+
return false unless project_has_lib_dir?
|
19
|
+
|
20
|
+
Dir["#{Dir.pwd}/lib/**/*.rb"].each do |file|
|
21
|
+
return true if File.readlines(file).detect { |line| line.match(/\s*class\s+.*<\s+::Rails::Engine/) }
|
22
|
+
end
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
26
|
+
def project_has_lib_dir?
|
27
|
+
@project_has_lib_dir ||= Dir.exist?("#{Dir.pwd}/lib")
|
28
|
+
end
|
29
|
+
|
30
|
+
# Taken from https://stackoverflow.com/questions/11784109/detecting-operating-systems-in-ruby/13586108
|
31
|
+
def operating_system_name
|
32
|
+
@operating_system_name ||= begin
|
33
|
+
host_os = RbConfig::CONFIG['host_os']
|
34
|
+
case host_os
|
35
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
36
|
+
:windows
|
37
|
+
when /darwin|mac os/
|
38
|
+
:macosx
|
39
|
+
when /linux/
|
40
|
+
:linux
|
41
|
+
when /solaris|bsd/
|
42
|
+
:unix
|
43
|
+
else
|
44
|
+
:unknown
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def is_linux?
|
50
|
+
operating_system_name == :linux
|
51
|
+
end
|
52
|
+
|
53
|
+
def is_mac?
|
54
|
+
operating_system_name == :maxosx
|
55
|
+
end
|
56
|
+
|
57
|
+
def xvfb_installed?
|
58
|
+
@xvfb_installed ||= RspecStarter.which("xvfb-run")
|
59
|
+
end
|
60
|
+
|
61
|
+
def xvfb_not_installed?
|
62
|
+
!xvfb_installed?
|
63
|
+
end
|
64
|
+
|
65
|
+
# This is ugly, but it gives us some added flexibility. Users can invoke the rspec_starter method from any script or
|
66
|
+
# executable. This method attempts to find out the file name of the script/exectuable.
|
67
|
+
#
|
68
|
+
# This method may not return a pretty result in all cases, but it's decent if the user has defined a script in their project
|
69
|
+
# (possibly in the bin folder, or root of the project).
|
70
|
+
def starter_script_file_name
|
71
|
+
caller.last.split(":")[0]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# This module loads the legacy RspecStarter code that uses the non-block DSL. It will be removed in 2.0.0.
|
2
|
+
# The file is loaded when RspecStarter starts, but most of the legacy code is not loaded until the
|
3
|
+
# 'invoke_legacy_starter' method is called.
|
4
|
+
module RspecStarter
|
5
|
+
def self.invoke_legacy_starter(defaults)
|
6
|
+
require 'rspec_starter/legacy/legacy_runner'
|
7
|
+
# puts "[DEPRECATION NOTICE] Your #{helpers.starter_script_file_name} file uses an old method for starting RSpec.\n" \
|
8
|
+
# "RspecStarter 1.6.0 introduced a new interface that is faster and more flexible.\n" \
|
9
|
+
# "To upgrade:\n" \
|
10
|
+
# " 1. Run 'rspec_starter --init' to install a new bin/start_rspec file.\n" \
|
11
|
+
# " 2. Your old bin/start_rspec will be renamed to bin/start_rspec.bak. If you customized\n" \
|
12
|
+
# " this file, open it up and consider moving the changes to the new bin/start_rspec file.\n" \
|
13
|
+
# " See https://github.com/roberts1000/rspec_starter for instructions on the new interface.\n".colorize(:yellow)
|
14
|
+
LegacyRunner.new(defaults).run
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module RspecStarter
|
2
|
+
# Method that support the help option on the bin/start_rspec script.
|
3
|
+
module Help
|
4
|
+
def should_show_help?
|
5
|
+
ARGV.any? { |option| option.include? "--help" }
|
6
|
+
end
|
7
|
+
|
8
|
+
def show_help
|
9
|
+
# Figure out the file name that invoked the rspec_starter helper. This is the name of the script; it be called anything.
|
10
|
+
script_name = calling_file_name
|
11
|
+
puts "Usage: #{script_name.colorize(:light_blue)} #{'[options] [options for RSpec]'.colorize(:light_blue)}\n"
|
12
|
+
puts " #{script_name} will look for its own options first then pass any remaining options to rspec"
|
13
|
+
|
14
|
+
# rubocop:disable Metrics/LineLength
|
15
|
+
puts "\nOptions: (run 'rspec --help' to see RSpec's options)"
|
16
|
+
puts " #{'--no-xvfb'.colorize(:light_blue)} DO NOT run XVFB (this can speed up RSpec when running tests that don't need XVFB)"
|
17
|
+
puts " #{'--no-prep'.colorize(:light_blue)} DO NOT prepare the test database (can speed up testing if you know the DB is clean)"
|
18
|
+
|
19
|
+
puts "\nExamples:"
|
20
|
+
puts " #{script_name.colorize(:light_blue)} #{'spec/features'.colorize(:light_blue)} (only run specs in the specs/features folder)"
|
21
|
+
puts " #{script_name.colorize(:light_blue)} #{'spec/features/some_spec:53'.colorize(:light_blue)} (run the spec on line 53 of the spec/features_some_spec.rb file)"
|
22
|
+
puts " #{script_name.colorize(:light_blue)} #{'--no-xvfb'.colorize(:light_blue)} #{'spec/requests/some_spec'.colorize(:light_blue)} (don't start XVFB since it's not needed for request specs)"
|
23
|
+
puts " #{'SIMPLECOV_FORMATTER=rcov'.colorize(:light_blue)} #{script_name.colorize(:light_blue)} (use with environment variables)\n"
|
24
|
+
# rubocop:enable Metrics/LineLength
|
25
|
+
end
|
26
|
+
|
27
|
+
# This is ugly, but it gives us some added flexibility. Users can invoke the rspec_starter method from any script or
|
28
|
+
# executable. This method attempts to find out the name of the script/exectuable.
|
29
|
+
# "caller" returns the method stack, and because of the location of this file in the gem, we happen to be the 4th item in the
|
30
|
+
# the array (hence "caller[3]" below).
|
31
|
+
#
|
32
|
+
# This method may not return a pretty result in all cases, but it's decent if the user has defined a script in their project
|
33
|
+
# (possibly in the bin folder, or root of the project).
|
34
|
+
def calling_file_name
|
35
|
+
# rubocop:disable Performance/Caller
|
36
|
+
caller[3].split(":")[0]
|
37
|
+
# rubocop:enable Performance/Caller
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
require_relative 'help'
|
5
|
+
require_relative 'steps/step'
|
6
|
+
require_relative 'steps/verify_xvfb_step'
|
7
|
+
require_relative 'steps/prepare_database_step'
|
8
|
+
require_relative 'steps/remove_tmp_folder_step'
|
9
|
+
require_relative 'steps/invoke_rspec_step'
|
10
|
+
|
11
|
+
module RspecStarter
|
12
|
+
# This is a simple class that encapulates the process of running RSpec. When a Runner is created, it creates a set of
|
13
|
+
# steps that will be executed, in order, when the 'run' method is invoked. Each step encapsulates an action that can be
|
14
|
+
# taken to help invoke Rspec. Steps are typically independent do not depend on information from other steps. However
|
15
|
+
# this is not a hard rule. If more complex steps are needed, feel free to create them. Each steps knows about the main
|
16
|
+
# runner object, so the runner object is a good place to store shared info.
|
17
|
+
class LegacyRunner
|
18
|
+
include Help
|
19
|
+
attr_reader :xvfb_installed, :step_num, :steps
|
20
|
+
|
21
|
+
def initialize(defaults)
|
22
|
+
@steps = []
|
23
|
+
@step_num = 1
|
24
|
+
@xvfb_installed = RspecStarter.which("xvfb-run")
|
25
|
+
@prep_db_step = PrepareDatabaseStep.new(defaults, self)
|
26
|
+
@run_rspec_step = InvokeRspecStep.new(defaults, self)
|
27
|
+
@steps << VerifyXvfbStep.new(defaults, self)
|
28
|
+
@steps << @prep_db_step
|
29
|
+
@steps << RemoveTmpFolderStep.new(defaults, self)
|
30
|
+
@steps << @run_rspec_step
|
31
|
+
end
|
32
|
+
|
33
|
+
def run
|
34
|
+
return show_help if should_show_help? # If we show help, exit and don't do anything else.
|
35
|
+
|
36
|
+
@steps.each do |step|
|
37
|
+
next unless step.should_execute?
|
38
|
+
|
39
|
+
step.execute
|
40
|
+
@step_num += 1
|
41
|
+
break if step.failed?
|
42
|
+
end
|
43
|
+
|
44
|
+
finalize_exit
|
45
|
+
end
|
46
|
+
|
47
|
+
def project_is_rails_app?
|
48
|
+
File.file?(File.join(Dir.pwd, 'config', 'application.rb'))
|
49
|
+
end
|
50
|
+
|
51
|
+
def project_is_rails_engine?
|
52
|
+
return false unless project_has_lib_dir?
|
53
|
+
|
54
|
+
Dir["#{Dir.pwd}/lib/**/*.rb"].each do |file|
|
55
|
+
return true if File.readlines(file).detect { |line| line.match(/\s*class\s+.*<\s+::Rails::Engine/) }
|
56
|
+
end
|
57
|
+
false
|
58
|
+
end
|
59
|
+
|
60
|
+
def project_has_lib_dir?
|
61
|
+
Dir.exist?("#{Dir.pwd}/lib")
|
62
|
+
end
|
63
|
+
|
64
|
+
def operating_system_name
|
65
|
+
result = `uname`
|
66
|
+
return 'Linux' if result.include?('Linux')
|
67
|
+
return 'MacOS' if result.include?('Darwin')
|
68
|
+
|
69
|
+
'Unknown'
|
70
|
+
end
|
71
|
+
|
72
|
+
def is_linux?
|
73
|
+
operating_system_name == 'Linux'
|
74
|
+
end
|
75
|
+
|
76
|
+
def is_mac?
|
77
|
+
operating_system_name == 'MacOS'
|
78
|
+
end
|
79
|
+
|
80
|
+
def xvfb_installed?
|
81
|
+
@xvfb_installed
|
82
|
+
end
|
83
|
+
|
84
|
+
def finalize_exit
|
85
|
+
exit(1) if @run_rspec_step.rspec_exit_status.nonzero?
|
86
|
+
exit(1) if @prep_db_step.exit_status.nonzero?
|
87
|
+
exit(0)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -5,6 +5,7 @@ module RspecStarter
|
|
5
5
|
|
6
6
|
def initialize(defaults, runner)
|
7
7
|
super(runner)
|
8
|
+
|
8
9
|
@allow_xvfb = defaults.fetch(:allow_xvfb, true)
|
9
10
|
@relevant_options = ["--no-xvfb"]
|
10
11
|
@success_or_skipped = nil # Will be updated once step executes
|
@@ -42,6 +43,7 @@ module RspecStarter
|
|
42
43
|
return base if @runner.is_mac?
|
43
44
|
return base unless @allow_xvfb
|
44
45
|
return base if @user_wants_to_skip_xvfb
|
46
|
+
|
45
47
|
@runner.xvfb_installed? ? "xvfb-run #{base}" : base
|
46
48
|
end
|
47
49
|
end
|
@@ -5,6 +5,7 @@ module RspecStarter
|
|
5
5
|
|
6
6
|
def initialize(defaults, runner)
|
7
7
|
super(runner)
|
8
|
+
|
8
9
|
@prepare_database = defaults.fetch(:prepare_db, true)
|
9
10
|
@relevant_options << '--no-prep-db'
|
10
11
|
@user_wants_to_skip = ARGV.any? { |option| option.include?("--no-prep-db") }
|
@@ -19,6 +20,7 @@ module RspecStarter
|
|
19
20
|
def should_execute?
|
20
21
|
return false if @user_wants_to_skip
|
21
22
|
return false unless @prepare_database
|
23
|
+
|
22
24
|
@runner.project_is_rails_app? || @runner.project_is_rails_engine?
|
23
25
|
end
|
24
26
|
|
@@ -41,7 +43,6 @@ module RspecStarter
|
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
|
-
|
45
46
|
private
|
46
47
|
|
47
48
|
def rebuild_command
|
@@ -52,6 +53,7 @@ module RspecStarter
|
|
52
53
|
# return a zero exit status. We need to see if 'rake aborted!' has been written to the output.
|
53
54
|
def successful?(stderr)
|
54
55
|
return false if @exit_status.nonzero?
|
56
|
+
|
55
57
|
!stderr.include?("rake aborted!")
|
56
58
|
end
|
57
59
|
end
|
@@ -3,6 +3,7 @@ module RspecStarter
|
|
3
3
|
class RemoveTmpFolderStep < RspecStarter::Step
|
4
4
|
def initialize(defaults, runner)
|
5
5
|
super(runner)
|
6
|
+
|
6
7
|
@remove_tmp_folder = defaults.fetch(:remove_tmp, true)
|
7
8
|
@runner = runner
|
8
9
|
@relevant_options << "--no-remove-tmp"
|
@@ -16,11 +17,13 @@ module RspecStarter
|
|
16
17
|
|
17
18
|
def should_execute?
|
18
19
|
return false if @user_wants_to_skip_removal
|
20
|
+
|
19
21
|
@remove_tmp_folder
|
20
22
|
end
|
21
23
|
|
22
24
|
def execute
|
23
25
|
return @success_or_skipped = true unless should_execute?
|
26
|
+
|
24
27
|
existed_before = tmp_folder_exists?
|
25
28
|
|
26
29
|
print "[#{@runner.step_num}] Removing #{'tmp'.colorize(:light_blue)} folder ... "
|
File without changes
|
@@ -5,6 +5,7 @@ module RspecStarter
|
|
5
5
|
class VerifyXvfbStep < RspecStarter::Step
|
6
6
|
def initialize(defaults, runner)
|
7
7
|
super(runner)
|
8
|
+
|
8
9
|
@relevant_options << '--no-xvfb'
|
9
10
|
@use_xvfb = defaults.fetch(:use_xvfb, true)
|
10
11
|
@user_wants_to_skip_xvfb = ARGV.any? { |option| option.include?("--no-xvfb") }
|
@@ -21,6 +22,7 @@ module RspecStarter
|
|
21
22
|
|
22
23
|
def should_execute?
|
23
24
|
return false if @user_wants_to_skip_xvfb
|
25
|
+
|
24
26
|
@use_xvfb
|
25
27
|
end
|
26
28
|
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module RspecStarter
|
2
|
+
# Option objects hold the information that Step subclasses want to register as options.
|
3
|
+
class Option
|
4
|
+
attr_reader :name, :default, :description, :key, :owner, :switch, :switch_description
|
5
|
+
|
6
|
+
def initialize(name:, default:, description: "", owner:, switch:, switch_description: "")
|
7
|
+
@owner = owner
|
8
|
+
@switch = switch
|
9
|
+
@switch_description = switch_description
|
10
|
+
@simplified_switch = switch.nil? ? nil : self.class.simplified_switch_name(switch)
|
11
|
+
@description = description
|
12
|
+
@default = default
|
13
|
+
self.name = name
|
14
|
+
@key = name || @simplified_switch
|
15
|
+
validate
|
16
|
+
end
|
17
|
+
|
18
|
+
def name=(value)
|
19
|
+
@name = value.nil? ? nil : value.to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
# Remove leading hyphens
|
23
|
+
# Convert remaining hyphens to underscores
|
24
|
+
# Undercase
|
25
|
+
def self.simplified_switch_name(switch)
|
26
|
+
switch.sub(/^-*/, "").sub("-", "_").underscore
|
27
|
+
end
|
28
|
+
|
29
|
+
# Does this option apply to the DSL inside the RspecStarter.start block. If so, users can use it like this:
|
30
|
+
# RspecStarter.start do
|
31
|
+
# task :foo, option_name_here: "some_value"
|
32
|
+
# end
|
33
|
+
def is_dsl_option?
|
34
|
+
!name.nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def validate
|
40
|
+
validate_name_has_no_hyphens
|
41
|
+
validate_switch_starts_with_hyphens
|
42
|
+
validate_name_or_switch_present
|
43
|
+
validate_default_is_true_false_for_switch
|
44
|
+
validate_switch_is_like_name
|
45
|
+
end
|
46
|
+
|
47
|
+
def validate_name_has_no_hyphens
|
48
|
+
return unless name
|
49
|
+
return unless name.include?("-")
|
50
|
+
|
51
|
+
raise "#{owner.name}#register_options is trying to register #{name}. Option names should not include hyphens"
|
52
|
+
end
|
53
|
+
|
54
|
+
def validate_switch_starts_with_hyphens
|
55
|
+
return unless switch
|
56
|
+
return unless switch[0] != "-" || switch[2] == "-"
|
57
|
+
|
58
|
+
raise "#{owner.name}#register_options is trying to register switch #{switch}. The switch name must start with '--' or '-'"
|
59
|
+
end
|
60
|
+
|
61
|
+
def validate_name_or_switch_present
|
62
|
+
return unless switch.nil? && name.nil?
|
63
|
+
|
64
|
+
raise "#{owner.name}#register_options is trying to create an option but 'name:' or 'switch:' are not specified. " \
|
65
|
+
"At least one must be specified."
|
66
|
+
end
|
67
|
+
|
68
|
+
def validate_default_is_true_false_for_switch
|
69
|
+
return unless switch && ![true, false].include?(default)
|
70
|
+
|
71
|
+
raise "#{owner.name}#register_options is trying to create an option for switch #{switch}. Options with switches " \
|
72
|
+
"can only return true/false. Set the 'default' argument to true or false for the option."
|
73
|
+
end
|
74
|
+
|
75
|
+
def validate_switch_is_like_name
|
76
|
+
return unless !switch.nil? && !name.nil?
|
77
|
+
return if name == @simplified_switch
|
78
|
+
|
79
|
+
raise "#{owner.name}#register_options is trying to create an option with name #{name} and switch #{switch}. " \
|
80
|
+
"The switch must be the same as the name when hyphens are converted to underscores and leading hyphens " \
|
81
|
+
"are removed."
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module RspecStarter
|
2
|
+
# Manages the option registration process for the Step subclasses.
|
3
|
+
# Holds raw option information so it can organized when steps run.
|
4
|
+
class Options
|
5
|
+
attr_reader :present_switches, :registered_task_options, :rspec_args_string
|
6
|
+
|
7
|
+
def initialize(environment, args)
|
8
|
+
@environment = environment
|
9
|
+
# These are the ARGV args that are passed to the command line.
|
10
|
+
@command_line_args = args
|
11
|
+
# Task classes that are used in the RspecStarter.start block: VerifyDisplayServer, StartRspec, etc...
|
12
|
+
@task_classes = environment.unique_task_classes
|
13
|
+
# The options that each Task wants to use.
|
14
|
+
@registered_task_options = {}
|
15
|
+
|
16
|
+
# Tasks register the command line switches they care about and RspecStarter has some global switches that it uses. This
|
17
|
+
# holds the list of switches that the user provided that match a task switch or a global switch. If the user doesn't
|
18
|
+
# supply a switch, or supplies a switch that nobody cares about, this will be an empty list.
|
19
|
+
@present_switches = nil
|
20
|
+
|
21
|
+
load_registered_task_options
|
22
|
+
initialize_present_switches
|
23
|
+
|
24
|
+
# The args that should be passed to rspec when it starts.
|
25
|
+
@rspec_args_string = nil
|
26
|
+
initialize_rspec_args_string
|
27
|
+
end
|
28
|
+
|
29
|
+
# If 'switch' is given, the option can only return 'true' or 'false'. 'default' must be set to 'true' or 'false'. When
|
30
|
+
# the switch isn't specified the user, the default (which must be true/false) is return. When the user specifies the default
|
31
|
+
# !default is returned.
|
32
|
+
|
33
|
+
# If switch is not given, default an be set to anything.
|
34
|
+
|
35
|
+
# If name isn't specified, this option is only a commandline switch.
|
36
|
+
# If name is specified, this option can be used inside the start block on a task.
|
37
|
+
def register_task_option(klass, name: nil, default: nil, description: "", switch: nil, switch_description: "")
|
38
|
+
new_option = RspecStarter::Option.new(name: name, default: default, description: description, owner: klass, switch: switch,
|
39
|
+
switch_description: switch_description)
|
40
|
+
@registered_task_options[klass] << new_option
|
41
|
+
end
|
42
|
+
|
43
|
+
def all_task_options
|
44
|
+
hash = {}
|
45
|
+
@registered_task_options.each do |_task_class, options|
|
46
|
+
options.each do |option|
|
47
|
+
hash[option.switch] = option unless hash.has_key?(option.switch)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
list = []
|
52
|
+
hash.each { |_switch, option| list << option }
|
53
|
+
list
|
54
|
+
end
|
55
|
+
|
56
|
+
def all_switches
|
57
|
+
(global_switches + all_task_switches).sort
|
58
|
+
end
|
59
|
+
|
60
|
+
def global_switches
|
61
|
+
['--help', '-h']
|
62
|
+
end
|
63
|
+
|
64
|
+
def all_task_switches
|
65
|
+
list = Set.new
|
66
|
+
@registered_task_options.each do |_task_class, options|
|
67
|
+
options.each { |option| list << option.switch unless option.switch.nil? }
|
68
|
+
end
|
69
|
+
list.to_a
|
70
|
+
end
|
71
|
+
|
72
|
+
def registered_task_option(task_class)
|
73
|
+
@registered_task_options[task_class]
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def initialize_rspec_args_string
|
79
|
+
list = @command_line_args.dup
|
80
|
+
all_switches.each { |switch| list.delete(switch) }
|
81
|
+
@rspec_args_string = list.join(" ")
|
82
|
+
end
|
83
|
+
|
84
|
+
def load_registered_task_options
|
85
|
+
# Give each step class the ability to register options that we should know about.
|
86
|
+
@task_classes.each do |klass|
|
87
|
+
@registered_task_options[klass] = []
|
88
|
+
klass.provide_options_to(self)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def initialize_present_switches
|
93
|
+
@present_switches = all_switches.select { |switch| @command_line_args.include?(switch) }.to_a
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|