|
- # frozen_string_literal: true
-
- # rubocop:disable Style/ClassVars
- require 'spec_helper'
- require 'cucumber/glue/registry_and_more'
- require 'support/fake_objects'
-
- module Cucumber
- module Glue
- describe StepDefinition do
- let(:id) { double }
- let(:user_interface) { double('user interface') }
- let(:support_code) { Cucumber::Runtime::SupportCode.new(user_interface) }
- let(:registry) { support_code.registry }
- let(:test_case) { double('scenario', language: 'en').as_null_object }
- let(:dsl) do
- registry
- Object.new.extend(Cucumber::Glue::Dsl)
- end
-
- before do
- registry.begin_scenario(test_case)
- @@inside = nil
- end
-
- def run_step(text)
- step_match(text).invoke(MultilineArgument::None.new)
- end
-
- def step_match(text)
- StepMatchSearch.new(registry.method(:step_matches), Configuration.default).call(text).first
- end
-
- it 'allows calling of other steps' do
- dsl.Given(/Outside/) do
- step 'Inside'
- end
- dsl.Given(/Inside/) do
- @@inside = true
- end
-
- run_step 'Outside'
-
- expect(@@inside).to be true
- end
-
- it 'allows calling of other steps with inline arg' do
- dsl.Given(/Outside/) do
- step 'Inside', table([['inside']])
- end
- dsl.Given(/Inside/) do |t|
- @@inside = t.raw[0][0]
- end
-
- run_step 'Outside'
-
- expect(@@inside).to eq 'inside'
- end
-
- context 'mapping to world methods' do
- it 'calls a method on the world when specified with a symbol' do
- expect(registry.current_world).to receive(:with_symbol)
-
- dsl.Given(/With symbol/, :with_symbol)
-
- run_step 'With symbol'
- end
-
- it 'calls a method on a specified object' do
- target = double('target')
-
- allow(registry.current_world).to receive(:target) { target }
-
- dsl.Given(/With symbol on block/, :with_symbol, on: -> { target })
-
- expect(target).to receive(:with_symbol)
-
- run_step 'With symbol on block'
- end
-
- it 'calls a method on a specified world attribute' do
- target = double('target')
-
- allow(registry.current_world).to receive(:target) { target }
-
- dsl.Given(/With symbol on symbol/, :with_symbol, on: :target)
-
- expect(target).to receive(:with_symbol)
-
- run_step 'With symbol on symbol'
- end
-
- it 'has the correct location' do
- dsl.Given(/With symbol/, :with_symbol)
- expect(step_match('With symbol').file_colon_line).to eq "spec/cucumber/glue/step_definition_spec.rb:#{__LINE__ - 1}"
- end
- end
-
- it 'raises UndefinedDynamicStep when inside step is not defined' do
- dsl.Given(/Outside/) do
- step 'Inside'
- end
-
- expect { run_step 'Outside' }.to raise_error(Cucumber::UndefinedDynamicStep)
- end
-
- it 'raises UndefinedDynamicStep when an undefined step is parsed dynamically' do
- dsl.Given(/Outside/) do
- steps %(
- Given Inside
- )
- end
-
- expect { run_step 'Outside' }.to raise_error(Cucumber::UndefinedDynamicStep)
- end
-
- it 'raises UndefinedDynamicStep when an undefined step with doc string is parsed dynamically' do
- dsl.Given(/Outside/) do
- steps %(
- Given Inside
- """
- abc
- """
- )
- end
-
- expect { run_step 'Outside' }.to raise_error(Cucumber::UndefinedDynamicStep)
- end
-
- it 'raises UndefinedDynamicStep when an undefined step with data table is parsed dynamically' do
- dsl.Given(/Outside/) do
- steps %(
- Given Inside
- | a |
- | 1 |
- )
- end
-
- expect { run_step 'Outside' }.to raise_error(Cucumber::UndefinedDynamicStep)
- end
-
- it 'allows forced pending' do
- dsl.Given(/Outside/) do
- pending('Do me!')
- end
-
- expect { run_step 'Outside' }.to raise_error(Cucumber::Pending, 'Do me!')
- end
-
- it 'raises ArityMismatchError when the number of capture groups differs from the number of step arguments' do
- dsl.Given(/No group: \w+/) do |arg|
- end
-
- expect { run_step 'No group: arg' }.to raise_error(Cucumber::Glue::ArityMismatchError)
- end
-
- it 'does not modify the step_match arg when arg is modified in a step' do
- dsl.Given(/My car is (.*)/) do |colour|
- colour << 'xxx'
- end
-
- step_name = 'My car is white'
- step_args = step_match(step_name).args
-
- expect { run_step step_name }.not_to change { step_args.first } # rubocop:disable Lint/AmbiguousBlockAssociation
- end
-
- context 'with ParameterType' do
- before(:each) do
- @actor = nil
-
- dsl.ParameterType(
- name: 'actor',
- regexp: /[A-Z]{1}[a-z]+/,
- transformer: ->(name) { @actor = FakeObjects::Actor.new(name) }
- )
- end
-
- it 'uses the instance created by the ParameterType transformer proc' do
- dsl.Given 'capture this: {actor}' do |arg|
- expect(arg.name).to eq 'Anjie'
- expect(arg).to be @actor
- end
-
- run_step 'capture this: Anjie'
- end
-
- it 'does not modify the step_match arg when arg is modified in a step' do
- dsl.Given 'capture this: {actor}' do |actor|
- actor.name = 'Dave'
- end
-
- run_step 'capture this: Anjie'
- step_args = step_match('capture this: Anjie').args
- expect(step_args[0].name).to_not eq 'Dave'
- expect(step_args[0].name).to eq 'Anjie'
- end
- end
-
- context 'allows log' do
- it 'calls "attach" with the correct media type' do
- expect(user_interface).to receive(:attach).with('wasup', 'text/x.cucumber.log+plain')
- dsl.Given(/Loud/) do
- log 'wasup'
- end
- run_step 'Loud'
- end
-
- it 'calls `to_s` if the message is not a String' do
- expect(user_interface).to receive(:attach).with('["Not", 1, "string"]', 'text/x.cucumber.log+plain')
- dsl.Given(/Loud/) do
- log ['Not', 1, 'string']
- end
- run_step 'Loud'
- end
- end
-
- it 'recognizes $arg style captures' do
- arg_value = 'up'
- dsl.Given 'capture this: {word}' do |arg|
- expect(arg).to eq arg_value
- end
- run_step 'capture this: up'
- end
-
- it 'has a JSON representation of the signature' do
- expect(StepDefinition.new(
- id,
- registry,
- /I CAN HAZ (\d+) CUKES/i,
- -> {},
- {}
- ).to_hash).to eq(
- source: {
- type: 'regular expression',
- expression: 'I CAN HAZ (\\d+) CUKES'
- },
- regexp: {
- source: 'I CAN HAZ (\\d+) CUKES', flags: 'i'
- }
- )
- end
- end
- end
- end
- # rubocop:enable Style/ClassVars
|