You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

configuration.rb 7.0 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. # frozen_string_literal: true
  2. require 'cucumber/constantize'
  3. require 'cucumber/cli/rerun_file'
  4. require 'cucumber/events'
  5. require 'cucumber/messages'
  6. require 'cucumber/core/event_bus'
  7. require 'cucumber/core/test/result'
  8. require 'forwardable'
  9. require 'cucumber'
  10. module Cucumber
  11. # The base class for configuring settings for a Cucumber run.
  12. class Configuration
  13. include Constantize
  14. extend Forwardable
  15. def self.default
  16. new
  17. end
  18. # Subscribe to an event.
  19. #
  20. # See {Cucumber::Events} for the list of possible events.
  21. #
  22. # @param event_id [Symbol, Class, String] Identifier for the type of event to subscribe to
  23. # @param handler_object [Object optional] an object to be called when the event occurs
  24. # @yield [Object] Block to be called when the event occurs
  25. # @method on_event
  26. def_instance_delegator :event_bus, :on, :on_event
  27. # @private
  28. def notify(message, *args)
  29. event_bus.send(message, *args)
  30. end
  31. def initialize(user_options = {})
  32. @options = default_options.merge(Hash(user_options))
  33. end
  34. def with_options(new_options)
  35. self.class.new(@options.merge(new_options))
  36. end
  37. def out_stream
  38. @options[:out_stream]
  39. end
  40. def error_stream
  41. @options[:error_stream]
  42. end
  43. def randomize?
  44. @options[:order] == 'random'
  45. end
  46. def seed
  47. @options[:seed]
  48. end
  49. def dry_run?
  50. @options[:dry_run]
  51. end
  52. def publish_enabled?
  53. @options[:publish_enabled]
  54. end
  55. def publish_quiet?
  56. @options[:publish_quiet]
  57. end
  58. def fail_fast?
  59. @options[:fail_fast]
  60. end
  61. def retry_attempts
  62. @options[:retry]
  63. end
  64. def retry_total_tests
  65. @options[:retry_total]
  66. end
  67. def guess?
  68. @options[:guess]
  69. end
  70. def strict
  71. @options[:strict]
  72. end
  73. def wip?
  74. @options[:wip]
  75. end
  76. def expand?
  77. @options[:expand]
  78. end
  79. def source?
  80. @options[:source]
  81. end
  82. def duration?
  83. @options[:duration]
  84. end
  85. def snippets?
  86. @options[:snippets]
  87. end
  88. def skip_profile_information?
  89. @options[:skip_profile_information]
  90. end
  91. def profiles
  92. @options[:profiles] || []
  93. end
  94. def custom_profiles
  95. profiles - [@options[:default_profile]]
  96. end
  97. def paths
  98. @options[:paths]
  99. end
  100. def formats
  101. @options[:formats]
  102. end
  103. def autoload_code_paths
  104. @options[:autoload_code_paths]
  105. end
  106. def snippet_type
  107. @options[:snippet_type]
  108. end
  109. def feature_dirs
  110. dirs = paths.map { |f| File.directory?(f) ? f : File.dirname(f) }.uniq
  111. dirs.delete('.') unless paths.include?('.')
  112. with_default_features_path(dirs)
  113. end
  114. def tag_limits
  115. @options[:tag_limits]
  116. end
  117. def tag_expressions
  118. @options[:tag_expressions]
  119. end
  120. def name_regexps
  121. @options[:name_regexps]
  122. end
  123. def filters
  124. @options[:filters]
  125. end
  126. def feature_files
  127. potential_feature_files = with_default_features_path(paths).map do |path|
  128. path = path.tr('\\', '/') # In case we're on windows. Globs don't work with backslashes.
  129. path = path.chomp('/')
  130. # TODO: Move to using feature loading strategies stored in
  131. # options[:feature_loaders]
  132. if File.directory?(path)
  133. Dir["#{path}/**/*.feature"].sort
  134. elsif Cli::RerunFile.can_read?(path)
  135. Cli::RerunFile.new(path).features
  136. else
  137. path
  138. end
  139. end.flatten.uniq
  140. remove_excluded_files_from(potential_feature_files)
  141. potential_feature_files
  142. end
  143. def support_to_load
  144. support_files = all_files_to_load.select { |f| f =~ /\/support\// }
  145. # env_files are separated from other_files so we can ensure env files
  146. # load first.
  147. #
  148. env_files = support_files.select { |f| f =~ /\/support\/env\..*/ }
  149. other_files = support_files - env_files
  150. env_files.reverse + other_files.reverse
  151. end
  152. def all_files_to_load
  153. files = require_dirs.map do |path|
  154. path = path.tr('\\', '/') # In case we're on windows. Globs don't work with backslashes.
  155. path = path.gsub(/\/$/, '') # Strip trailing slash.
  156. File.directory?(path) ? Dir["#{path}/**/*"] : path
  157. end.flatten.uniq
  158. remove_excluded_files_from(files)
  159. files.select! { |f| File.file?(f) }
  160. files.reject! { |f| File.extname(f) == '.feature' }
  161. files.reject! { |f| f =~ /^http/ }
  162. files.sort
  163. end
  164. def step_defs_to_load
  165. all_files_to_load.reject { |f| f =~ /\/support\// }
  166. end
  167. def formatter_factories
  168. formats.map do |format, formatter_options, path_or_io|
  169. factory = formatter_class(format)
  170. yield factory,
  171. formatter_options,
  172. path_or_io
  173. rescue Exception => e # rubocop:disable Lint/RescueException
  174. raise e, "#{e.message}\nError creating formatter: #{format}", e.backtrace
  175. end
  176. end
  177. def formatter_class(format)
  178. if (builtin = Cli::Options::BUILTIN_FORMATS[format])
  179. constantize(builtin[0])
  180. else
  181. constantize(format)
  182. end
  183. end
  184. def to_hash
  185. @options
  186. end
  187. # An array of procs that can generate snippets for undefined steps. These procs may be called if a
  188. # formatter wants to display snippets to the user.
  189. #
  190. # Each proc should take the following arguments:
  191. #
  192. # - keyword
  193. # - step text
  194. # - multiline argument
  195. # - snippet type
  196. #
  197. def snippet_generators
  198. @options[:snippet_generators] ||= []
  199. end
  200. def register_snippet_generator(generator)
  201. snippet_generators << generator
  202. self
  203. end
  204. def event_bus
  205. @options[:event_bus]
  206. end
  207. def id_generator
  208. @id_generator ||= Cucumber::Messages::IdGenerator::UUID.new
  209. end
  210. private
  211. def default_options
  212. {
  213. autoload_code_paths: ['features/support', 'features/step_definitions'],
  214. filters: [],
  215. strict: Cucumber::Core::Test::Result::StrictConfiguration.new,
  216. require: [],
  217. dry_run: false,
  218. publish_quiet: false,
  219. fail_fast: false,
  220. formats: [],
  221. excludes: [],
  222. tag_expressions: [],
  223. name_regexps: [],
  224. env_vars: {},
  225. diff_enabled: true,
  226. snippets: true,
  227. source: true,
  228. duration: true,
  229. event_bus: Cucumber::Events.make_event_bus,
  230. retry_total: Float::INFINITY
  231. }
  232. end
  233. def default_features_paths
  234. ['features']
  235. end
  236. def with_default_features_path(paths)
  237. return default_features_paths if paths.empty?
  238. paths
  239. end
  240. def remove_excluded_files_from(files)
  241. files.reject! { |path| @options[:excludes].detect { |pattern| path =~ pattern } }
  242. end
  243. def require_dirs
  244. if @options[:require].empty?
  245. default_features_paths + Dir['vendor/{gems,plugins}/*/cucumber']
  246. else
  247. @options[:require]
  248. end
  249. end
  250. end
  251. end

No Description

Contributors (1)