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.

support_code.rb 4.7 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. # frozen_string_literal: true
  2. require 'cucumber/constantize'
  3. require 'cucumber/runtime/for_programming_languages'
  4. require 'cucumber/runtime/step_hooks'
  5. require 'cucumber/runtime/before_hooks'
  6. require 'cucumber/runtime/after_hooks'
  7. require 'cucumber/gherkin/steps_parser'
  8. require 'cucumber/step_match_search'
  9. module Cucumber
  10. class Runtime
  11. class SupportCode
  12. require 'forwardable'
  13. class StepInvoker
  14. def initialize(support_code)
  15. @support_code = support_code
  16. end
  17. def steps(steps)
  18. steps.each { |step| step(step) }
  19. end
  20. def step(step)
  21. location = Core::Test::Location.of_caller
  22. @support_code.invoke_dynamic_step(step[:text], multiline_arg(step, location))
  23. end
  24. def multiline_arg(step, location)
  25. if !step[:doc_string].nil?
  26. MultilineArgument.from(step[:doc_string][:content], location, step[:doc_string][:content_type])
  27. elsif !step[:data_table].nil?
  28. MultilineArgument::DataTable.from(step[:data_table][:rows].map { |row| row[:cells].map { |cell| cell[:value] } })
  29. else
  30. MultilineArgument.from(nil)
  31. end
  32. end
  33. end
  34. include Constantize
  35. attr_reader :registry
  36. def initialize(user_interface, configuration = Configuration.default)
  37. @configuration = configuration
  38. # TODO: needs a better name, or inlining its methods
  39. @runtime_facade = Runtime::ForProgrammingLanguages.new(self, user_interface)
  40. @registry = Cucumber::Glue::RegistryAndMore.new(@runtime_facade, @configuration)
  41. end
  42. def configure(new_configuration)
  43. @configuration = Configuration.new(new_configuration)
  44. end
  45. # Invokes a series of steps +steps_text+. Example:
  46. #
  47. # invoke(%Q{
  48. # Given I have 8 cukes in my belly
  49. # Then I should not be thirsty
  50. # })
  51. def invoke_dynamic_steps(steps_text, iso_code, _location)
  52. parser = Cucumber::Gherkin::StepsParser.new(StepInvoker.new(self), iso_code)
  53. parser.parse(steps_text)
  54. end
  55. # @api private
  56. # This allows users to attempt to find, match and execute steps
  57. # from code as the features are running, as opposed to regular
  58. # steps which are compiled into test steps before execution.
  59. #
  60. # These are commonly called nested steps.
  61. def invoke_dynamic_step(step_name, multiline_argument, _location = nil)
  62. matches = step_matches(step_name)
  63. raise UndefinedDynamicStep, step_name if matches.empty?
  64. matches.first.invoke(multiline_argument)
  65. end
  66. def load_files!(files)
  67. log.debug("Code:\n")
  68. files.each do |file|
  69. load_file(file)
  70. end
  71. log.debug("\n")
  72. end
  73. def load_files_from_paths(paths)
  74. files = paths.map { |path| Dir["#{path}/**/*.rb"] }.flatten
  75. load_files! files
  76. end
  77. def unmatched_step_definitions
  78. registry.unmatched_step_definitions
  79. end
  80. def fire_hook(name, *args)
  81. # TODO: kill with fire
  82. registry.send(name, *args)
  83. end
  84. def step_definitions
  85. registry.step_definitions
  86. end
  87. def find_after_step_hooks(test_case)
  88. scenario = RunningTestCase.new(test_case)
  89. hooks = registry.hooks_for(:after_step, scenario)
  90. StepHooks.new(@configuration.id_generator, hooks, @configuration.event_bus)
  91. end
  92. def apply_before_hooks(test_case)
  93. return test_case if test_case.test_steps.empty?
  94. scenario = RunningTestCase.new(test_case)
  95. hooks = registry.hooks_for(:before, scenario)
  96. BeforeHooks.new(@configuration.id_generator, hooks, scenario, @configuration.event_bus).apply_to(test_case)
  97. end
  98. def apply_after_hooks(test_case)
  99. return test_case if test_case.test_steps.empty?
  100. scenario = RunningTestCase.new(test_case)
  101. hooks = registry.hooks_for(:after, scenario)
  102. AfterHooks.new(@configuration.id_generator, hooks, scenario, @configuration.event_bus).apply_to(test_case)
  103. end
  104. def find_around_hooks(test_case)
  105. scenario = RunningTestCase.new(test_case)
  106. registry.hooks_for(:around, scenario).map do |hook|
  107. Hooks.around_hook do |run_scenario|
  108. hook.invoke('Around', scenario, &run_scenario)
  109. end
  110. end
  111. end
  112. private
  113. def step_matches(step_name)
  114. StepMatchSearch.new(registry.method(:step_matches), @configuration).call(step_name)
  115. end
  116. def load_file(file)
  117. log.debug(" * #{file}\n")
  118. registry.load_code_file(file)
  119. end
  120. def log
  121. Cucumber.logger
  122. end
  123. end
  124. end
  125. end

No Description

Contributors (1)