diff --git a/Gemfile b/Gemfile index 86210e4..798c186 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ -source :rubygems +source 'https://rubygems.org' gemspec diff --git a/features/fixtures/fake_app.rb b/features/fixtures/fake_app.rb index a13a258..2f58dba 100644 --- a/features/fixtures/fake_app.rb +++ b/features/fixtures/fake_app.rb @@ -29,5 +29,10 @@ class FakeApp < Sinatra::Base input_data = JSON.parse request.env["rack.input"].read, symbolize_names: true status 201 if input_data == {publisher: 'Pragprog'} end + + put '/api/publishers/123' do + input_data = JSON.parse request.env["rack.input"].read, symbolize_names: true + status 200 if input_data == {publisher: 'Pragprog'} + end end end diff --git a/features/request.feature b/features/request.feature index 866e7a4..8b4abfd 100644 --- a/features/request.feature +++ b/features/request.feature @@ -7,6 +7,21 @@ Feature: """ Then the response status should be "200" + Scenario: GET request with defined instance variable method referenced from step + Given I define instance variable @defined = "BOOKS" + When I perform the following step: + """ + I send a GET request to "/api/[@defined.downcase]" + """ + Then the response status should be "200" + + Scenario: GET request with undefined instance variable referenced from step + When I perform the following steps which may raise ArgumentError: + """ + I send a GET request to "/api/[@undefined]" + """ + Then ArgumentError was raised + Scenario: POST request with params When I perform the following step with table: """ @@ -23,3 +38,12 @@ Feature: {"publisher": "Pragprog"} """ Then the response status should be "201" + + Scenario: PUT request with defined instance variable method referenced from step + Given I define instance variable @publisher = OpenStruct.new(:id => 123) + When I perform the following step with string: + """ + I send a PUT request to "/api/publishers/[@publisher.id]" with the following: + {"publisher": "Pragprog"} + """ + Then the response status should be "200" diff --git a/features/step_definitions/api_test_steps.rb b/features/step_definitions/api_test_steps.rb index 2b477e8..f7ba55e 100644 --- a/features/step_definitions/api_test_steps.rb +++ b/features/step_definitions/api_test_steps.rb @@ -1,10 +1,31 @@ require 'active_support/core_ext' +Given /^I define instance variable (@[\w]+) = (.*)$/ do |name, value| + instance_variable_set(name, eval(value)) +end + When /^I perform the following steps?:$/ do |step_strings| steps = step_strings.split("\n") steps.each {|step_string| step step_string } end +When /^I perform the following steps which may raise ([\w]+)?:$/ do |exception_name, step_strings| + exception_type = exception_name.constantize + steps = step_strings.split("\n") + steps.each do |step_string| + begin + step step_string + rescue exception_type => ex + @last_exception = ex + end + end +end + +Then /^([\w]+) was raised$/ do |exception_name| + exception_type = exception_name.constantize + @last_exception.should be_an_instance_of(exception_type) +end + Then /^the response should equal:$/ do |response_body| last_response.body.should eq(response_body) end diff --git a/lib/cucumber/api_steps.rb b/lib/cucumber/api_steps.rb index 0e1d496..0a11de9 100644 --- a/lib/cucumber/api_steps.rb +++ b/lib/cucumber/api_steps.rb @@ -14,6 +14,21 @@ def to_str end +module InstanceVarsInStepArguments + # @return [String] arg, replacing any '[@ivar.id]' sub strings by the value of @ivar.id + def interpolate_step_arg(arg) + r = /\[(@[^\]\s]+)\]/ + arg && arg.gsub(r) do + name, field = $1 && $1.split('.') + ivar = instance_variable_get(name) + raise ArgumentError, "undefined instance variable '#{name}'" unless ivar + field ? ivar.send(field) : ivar + end + end +end + +World(InstanceVarsInStepArguments) + Given /^I set headers:$/ do |headers| headers.rows_hash.each {|k,v| header k, v } end @@ -38,7 +53,7 @@ def to_str When /^I send a (GET|POST|PUT|DELETE) request (?:for|to) "([^"]*)"(?: with the following:)?$/ do |*args| request_type = args.shift - path = args.shift + path = interpolate_step_arg(args.shift) input = args.shift request_opts = {method: request_type.downcase.to_sym}