soaspec 0.2.8 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +0 -17
  3. data/ChangeLog +6 -0
  4. data/Gemfile +2 -2
  5. data/README.md +42 -9
  6. data/Rakefile +1 -1
  7. data/exe/soaspec +9 -14
  8. data/exe/xml_to_yaml_file +3 -3
  9. data/images/basic_demo.gif +0 -0
  10. data/lib/soaspec.rb +9 -19
  11. data/lib/soaspec/core_ext/hash.rb +10 -12
  12. data/lib/soaspec/cucumber/generic_steps.rb +1 -1
  13. data/lib/soaspec/exchange.rb +4 -1
  14. data/lib/soaspec/exchange_handlers/exchange_handler.rb +5 -4
  15. data/lib/soaspec/exchange_handlers/handler_accessors.rb +7 -3
  16. data/lib/soaspec/exchange_handlers/response_extractor.rb +55 -0
  17. data/lib/soaspec/exchange_handlers/rest_exchanger_factory.rb +1 -1
  18. data/lib/soaspec/exchange_handlers/rest_handler.rb +16 -43
  19. data/lib/soaspec/exchange_handlers/rest_methods.rb +1 -2
  20. data/lib/soaspec/exchange_handlers/rest_parameters.rb +6 -2
  21. data/lib/soaspec/exchange_handlers/rest_parameters_defaults.rb +1 -1
  22. data/lib/soaspec/exchange_handlers/soap_handler.rb +6 -10
  23. data/lib/soaspec/exchange_properties.rb +1 -2
  24. data/lib/soaspec/exe_helpers.rb +7 -9
  25. data/lib/soaspec/indifferent_hash.rb +1 -1
  26. data/lib/soaspec/interpreter.rb +1 -3
  27. data/lib/soaspec/matchers.rb +1 -2
  28. data/lib/soaspec/o_auth2.rb +2 -1
  29. data/lib/soaspec/spec_logger.rb +54 -12
  30. data/lib/soaspec/template_reader.rb +2 -1
  31. data/lib/soaspec/test_server/get_bank.rb +5 -5
  32. data/lib/soaspec/test_server/id_manager.rb +1 -3
  33. data/lib/soaspec/test_server/invoices.rb +0 -1
  34. data/lib/soaspec/test_server/puppy_service.rb +0 -1
  35. data/lib/soaspec/test_server/test_attribute.rb +0 -1
  36. data/lib/soaspec/version.rb +2 -2
  37. data/lib/soaspec/virtual_server.rb +1 -1
  38. data/lib/soaspec/wait.rb +1 -1
  39. data/lib/soaspec/wsdl_generator.rb +11 -3
  40. data/soaspec.gemspec +7 -2
  41. data/test_wsdl.rb +4 -7
  42. metadata +54 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a446e205c6a72dceb41dada3f7b910587629e0c0
4
- data.tar.gz: f827d2d372ff408503f1111175b78cfa028a845f
3
+ metadata.gz: 17d2693e9fd08ec36b86235d2fd0a5991ef252a3
4
+ data.tar.gz: 68ec551ebe49f36c211a9fd856c3b5b669f3b5f8
5
5
  SHA512:
6
- metadata.gz: 6cc6e07e30560774e7b5e9c9568bc15941df4cdfbb19102c97e322e53ffb3826d9d34d8e91cbb9182deb6745c710d23fef24dfb9d1c81688ae13131066f7f2e3
7
- data.tar.gz: dee062b10eafcef1e52c96137108b4bdc0013d633e2871d9a85227e116580939144466b87ddd9f025f27c4b44e22e0d49b70c52ba94e8652e7172f3d881c9ccb
6
+ metadata.gz: 718d1fde689c36a4e96fc0ac61645151de132c3202a7213e21a8adad01c48b0aa6a76cfb057597c86b6e0e31177ef69dfcf88139e2f9285ad93c9e279b14c872
7
+ data.tar.gz: 7f2808840766e5ae179efc5ae3afd3e9d91364f92bc3196db8b7432df29df3bd0e19eef5d149bea6a817198468ee075dfcca5a2b26a120dc6e9aff2d8425ab76
data/.gitlab-ci.yml CHANGED
@@ -19,23 +19,6 @@ cucumber:
19
19
  script:
20
20
  - bundle exec cucumber
21
21
 
22
- code_quality:
23
- image: ruby:2.5
24
- variables:
25
- DOCKER_DRIVER: overlay2
26
- allow_failure: true
27
- services:
28
- - docker:stable-dind
29
- script:
30
- - export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
31
- - docker run
32
- --env SOURCE_CODE="$PWD"
33
- --volume "$PWD":/code
34
- --volume /var/run/docker.sock:/var/run/docker.sock
35
- "registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
36
- artifacts:
37
- paths: [gl-code-quality-report.json]
38
-
39
22
  pages:
40
23
  stage: deploy
41
24
  dependencies:
data/ChangeLog CHANGED
@@ -1,3 +1,9 @@
1
+ Version 0.2.9
2
+ * Enhancements
3
+ * More documentation in README.md
4
+ * Started breaking up massive RestHandler more
5
+ * Allow one output logs to STDOUT through Soaspec::SpecLogger.output_to_terminal = true
6
+
1
7
  Version 0.2.8
2
8
  * Bug Fix
3
9
  * RSpec-its dependency produces a conflict. Remove specific version reference
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
- git_source(:gitlab) { |repo_name| "https://gitlab.com/samuel-garratt/soaspec" }
3
+ git_source(:gitlab) { |_repo_name| 'https://gitlab.com/samuel-garratt/soaspec' }
4
4
 
5
5
  # Specify your gem's dependencies in soaspec.gemspec
6
6
  gemspec
data/README.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # Soaspec
2
2
 
3
3
  This gem helps to represent multiple API tests against a backend briefly, concisely and clearly.
4
+
5
+ ![Soaspec example](images/basic_demo.gif)
6
+ > Example showing how a REST 'get' call can be made and it's response extracted.
7
+
8
+ [![Build Status](https://gitlab.com/samuel-garratt/soaspec/badges/master/build.svg)](https://gitlab.com/samuel-garratt/soaspec/pipelines)
9
+ [![Coverage](https://gitlab.com/samuel-garratt/soaspec/badges/master/coverage.svg)](https://samuel-garratt.gitlab.io/soaspec)
10
+
4
11
  It is essentially a wrapper around the Savon and RestClient gems, adding useful functionality including
5
12
 
6
13
  * Creating multiple API calls from the same base configuration through the use of an `ExchangeHandler` class
@@ -13,8 +20,6 @@ It is essentially a wrapper around the Savon and RestClient gems, adding useful
13
20
  * Accessing and utilising `oauth2` access tokens
14
21
  * Hosting a `virtual_server` that simulates REST & SOAP responses from an API
15
22
 
16
- [![Build Status](https://gitlab.com/samuel-garratt/soaspec/badges/master/build.svg)](https://gitlab.com/samuel-garratt/soaspec/pipelines)
17
- [![Coverage](https://gitlab.com/samuel-garratt/soaspec/badges/master/coverage.svg)](https://samuel-garratt.gitlab.io/soaspec)
18
23
  ## Installation
19
24
 
20
25
  Add this line to your application's Gemfile:
@@ -72,13 +77,18 @@ For example:
72
77
  ```ruby
73
78
  # Classes are set up through inheriting from either `Soaspec::RestHandler` or `Soaspec::SoapHandler`
74
79
  class PuppyService < Soaspec::RestHandler
80
+ # Set default headers for all `Exchanges` using this class
81
+ headers accept: 'application/json', content_type: 'application/json'
75
82
 
76
- headers accept: 'application/json', content_type: 'application/json' # Set default headers for all `Exchanges` using this class
83
+ # URL for which all requests using this class will start with
84
+ base_url 'http://petstore.swagger.io/v2/pet'
77
85
 
78
- base_url 'http://petstore.swagger.io/v2/pet' # URL for which all requests using this class will start with
86
+ # Accessing parts of a response
79
87
 
80
- element :id, :id # Define a method 'id' that can be obtained with either XPATH '//id' or JSONPath '$..id'
81
- element :category_id, '$..category.id' # Define method to obtain a category id through JSON Path
88
+ # Define a method 'id' that can be obtained with either XPATH '//id' or JSONPath '$..id'
89
+ element :id, :id
90
+ # Define method to obtain a category id through JSON Path
91
+ element :category_id, '$..category.id'
82
92
  end
83
93
  ```
84
94
 
@@ -91,17 +101,40 @@ Upon initialization of the Exchange object (or later on through setters), parame
91
101
  Most getters of the `Exchange` are on the response & will implicitly trigger the API request to be made.
92
102
  Once this request has been made, all following accessors of the response will just use the response of the previous request made.
93
103
 
94
- For example, to create a http post using the above `ExchangeHandler` and extract a value from the response body using JSON PATH.
104
+ For example, to create a http post using the above `ExchangeHandler` and get parts of it's response.
95
105
  ```ruby
96
- exchange = PuppyService.post(body: { status: 'sold' }) # The 'body' key will convert it's value from a Hash to JSON
97
106
  # Create a new Exchange that will post to 'http://petstore.swagger.io/v2/pet' with JSON { "status": "sold" }
107
+ # The 'body' key will convert it's value from a Hash to JSON
108
+ exchange = PuppyService.post(body: { status: 'sold' })
109
+
110
+ # This will trigger the request to be made & return the response, in this case a RestClient::Response object
111
+ response = exchange.response
112
+ # This will reuse the response already received return a value at JSON path $..category.id, throwing an exception if not found
98
113
  exchange.category_id
99
- # This will trigger the request to be made & return a value at JSON path $..category.id, throwing an exception if not found
114
+ # This will do the same but using path directly in code
115
+ exchange['$..category.id']
116
+ # Get the HTTP status code of the response
117
+ exchange.status_code
100
118
  ```
101
119
 
102
120
  See [Request Body Parameters](https://gitlab.com/samuel-garratt/soaspec/wikis/RequestBodyParameters) for more details on setting a request body.
103
121
  See [Creating an Exchange](https://gitlab.com/samuel-garratt/soaspec/wikis/CreatingExchange) for details on how to create an Exchange.
104
122
 
123
+ ### Virtual Server
124
+
125
+ Soaspec includes a virtual server that returns REST and SOAP responses that can be used when learning or experimenting with API testing.
126
+ The gem itself uses this to test it's own functionality.
127
+
128
+ To start the server, after installing the gem, type
129
+
130
+ ```
131
+ soaspec virtual_server [port_num]
132
+ ```
133
+
134
+ By default it runs on port 4999. This will be used if `port_num` is empty.
135
+
136
+ You can look at the documentation for the web services provided at the rool url (e.g `localhost:4999`).
137
+
105
138
  ### RSpec
106
139
 
107
140
  For example:
data/Rakefile CHANGED
@@ -27,4 +27,4 @@ end
27
27
 
28
28
  YARD::Rake::YardocTask.new do |t|
29
29
  t.files = %w[features/**/*.feature features/**/*.rb lib/soaspec/cucumber/*.rb] # lib/soaspec/cucumber/*.rb]
30
- end
30
+ end
data/exe/soaspec CHANGED
@@ -1,16 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
-
4
3
  require 'thor'
5
4
  $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
6
5
  require 'savon'
7
6
  require 'soaspec'
8
7
 
9
8
  module Soaspec
10
-
11
9
  # Common executable for Soaspec
12
10
  class Exe < Thor
13
-
14
11
  include Soaspec::ExeHelpers
15
12
  include Soaspec::WsdlGenerator
16
13
 
@@ -54,6 +51,7 @@ module Soaspec
54
51
  desc 'add [type] [name]', 'Add new ExchangeHandler'
55
52
  def add(type = 'rest', name = 'TestService')
56
53
  raise "Type '#{type}' is not available" unless %w[rest soap].include? type
54
+
57
55
  @name = name # Use instance variable for ERB
58
56
  create_file filename: File.join('lib', "#{name.snakecase}.rb"),
59
57
  content: retrieve_contents(File.join('lib', "new_#{type}_service.rb"))
@@ -87,30 +85,27 @@ module Soaspec
87
85
  @wsdl_doc = Savon.client(**savon_options).wsdl
88
86
  @wsdl_schemas = @wsdl_doc.parser.schemas
89
87
 
90
- create_file filename: 'Rakefile', ignore_if_present: true
91
- create_file filename: 'Gemfile', ignore_if_present: true
88
+ create_files %w[Rakefile Gemfile README.md spec/spec_helper.rb], ignore_if_present: true
92
89
  create_file(filename: '.rspec')
93
90
  create_file(filename: '.travis.yml') if options[:ci] == 'travis'
94
- create_file filename: 'README.md', ignore_if_present: true
95
- create_file filename: 'spec/spec_helper.rb', ignore_if_present: true
96
91
  create_folder 'logs'
97
92
  create_file filename: "lib/#{options[:name].snakecase}.rb", content: class_content
98
93
 
99
94
  # Files according to WSDL
100
- @wsdl_doc.operations.each do |operation, details|
95
+ @wsdl_doc.operations.each do |operation, op_details|
101
96
  puts "Creating files for operation: #{operation}"
102
97
  @content = "default:\n"
103
98
  @use_camel_case = false
104
- puts 'Message params: ' + details.to_s
99
+ puts 'Message params: ' + op_details.to_s
105
100
  # From namespace identifier, find namespace, and for that find schemaLocation xsd and use that to build request
106
- if details[:parameters]
107
- details[:parameters].each do |element, details|
108
- @use_camel_case = true if /[[:upper:]]/.match(element.to_s[0]) != nil
101
+ if op_details[:parameters]
102
+ op_details[:parameters].each do |element, details|
103
+ @use_camel_case = true unless /[[:upper:]]/.match(element.to_s[0]).nil?
109
104
  @content += " #{element.to_s.snakecase}: #{fill_in_field_from_type(details[:type])} # #{details[:type]} \n"
110
105
  # TODO: If details is a Hash need to loop again
111
106
  end
112
107
  end
113
- wsdl_to_yaml_for root_elements_for(details)
108
+ wsdl_to_yaml_for root_elements_for(op_details)
114
109
  params = []
115
110
  params << 'convert_request_keys_to: :camelcase' if @use_camel_case
116
111
  params_string = params == [] ? '' : ', ' + params.join(', ')
@@ -133,4 +128,4 @@ module Soaspec
133
128
  end
134
129
  end
135
130
 
136
- Soaspec::Exe.start(ARGV)
131
+ Soaspec::Exe.start(ARGV)
data/exe/xml_to_yaml_file CHANGED
@@ -4,7 +4,7 @@ require 'xmlsimple'
4
4
  require 'yaml'
5
5
  require 'fileutils'
6
6
 
7
- $LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
7
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
8
8
 
9
9
  require 'soaspec'
10
10
 
@@ -28,7 +28,7 @@ end
28
28
  def clean_up_yaml(yaml_string)
29
29
  yaml_string = yaml_string.gsub(/\R+(\s*)-/, '').gsub(/{}/, "''") # Remove arrays, {} -> ''
30
30
  # Insert new line where there are 2 ':' on 1 line. Issue from first gsub
31
- yaml_string.gsub(/:(\s)(\w*):/){|s| s.insert(1, "\n")}
31
+ yaml_string.gsub(/:(\s)(\w*):/) { |s| s.insert(1, "\n") }
32
32
  end
33
33
 
34
34
  if ARGV[0]
@@ -39,4 +39,4 @@ if ARGV[0]
39
39
  create_file(filename: ARGV[1] || default_output_file, content: yaml_file)
40
40
  else
41
41
  puts 'usage: xml_to_yaml_file [input.xml] [output.yml] '
42
- end
42
+ end
Binary file
data/lib/soaspec.rb CHANGED
@@ -36,7 +36,6 @@ require 'soaspec/wait'
36
36
 
37
37
  # Gem for handling SOAP and REST api tests
38
38
  module Soaspec
39
-
40
39
  @template_folder = 'templates'
41
40
  @auto_oauth = true
42
41
 
@@ -59,31 +58,21 @@ module Soaspec
59
58
  # Folder used to store credentials
60
59
  # Used in auth2_file command
61
60
  # @param [String] folder
62
- def credentials_folder=(folder)
63
- @credentials_folder = folder
64
- end
61
+ attr_writer :credentials_folder
65
62
 
66
63
  # Credentials folder used to store secret data (not in source control) E.g passwords
67
- def credentials_folder
68
- @credentials_folder
69
- end
64
+ attr_reader :credentials_folder
70
65
 
71
66
  # Used so that exchange class knows what context it's in
72
67
  # @param [ExchangeHandler] handler A class inheriting from Soaspec::ExchangeHandler. Exchange class uses this
73
- def api_handler=(handler)
74
- @api_handler = handler
75
- end
68
+ attr_writer :api_handler
76
69
 
77
70
  # Exchange Handler class currently being used
78
- def api_handler
79
- @api_handler
80
- end
71
+ attr_reader :api_handler
81
72
 
82
73
  # Set whether to transform strings to keys in request automatically
83
74
  # @param [Boolean] use_keys
84
- def always_use_keys=(use_keys)
85
- @always_use_keys = use_keys
86
- end
75
+ attr_writer :always_use_keys
87
76
 
88
77
  # @return [Boolean] Whether to transform strings to keys in request automatically
89
78
  def always_use_keys?
@@ -97,13 +86,14 @@ module Soaspec
97
86
 
98
87
  # Whether to log all API traffic
99
88
  def log_api_traffic=(set)
100
- @log_api_traffic = set
101
- RestClient.log = nil unless set
89
+ puts 'Soaspec.log_api_traffic= now deprecated. Please use Soaspec::SpecLogger.log_api_traffic= instead'
90
+ Soaspec::SpecLogger.log_api_traffic = set
102
91
  end
103
92
 
104
93
  # @return [Boolean] Whether to log all API traffic
105
94
  def log_api_traffic?
106
- @log_api_traffic.nil? ? true : @log_api_traffic
95
+ puts 'Soaspec.log_api_traffic? now deprecated. Please use Soaspec::SpecLogger.log_api_traffic? instead'
96
+ Soaspec::SpecLogger.log_api_traffic?
107
97
  end
108
98
  end
109
99
  end
@@ -1,28 +1,25 @@
1
-
2
-
3
-
4
1
  # Override Hash class with convience methods
5
2
  class Hash
6
-
7
3
  # Transform each key in Hash to a symbol. Privately used by non-self method
8
4
  def self.transform_keys_to_symbols(value)
9
- return value if not value.is_a?(Hash)
10
- hash = value.inject({}){|memo,(k,v)| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); memo}
11
- return hash
5
+ return value unless value.is_a?(Hash)
6
+
7
+ hash = value.each_with_object({}) { |(k, v), memo| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); }
8
+ hash
12
9
  end
13
10
 
14
11
  # Take keys of hash and transform those to a symbols
15
12
  def transform_keys_to_symbols
16
- inject({}){|memo, (k, v)| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); memo}
13
+ each_with_object({}) { |(k, v), memo| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); }
17
14
  end
18
15
 
19
16
  # Returns all keys that have a particular value within a nested Hash
20
17
  def find_all_values_for(key)
21
18
  result = []
22
19
  result << self[key]
23
- self.values.each do |hash_value|
24
- # next if hash_value.is_a? Array
25
- #
20
+ values.each do |hash_value|
21
+ # next if hash_value.is_a? Array
22
+ #
26
23
  if hash_value.is_a?(Array)
27
24
  hash_value.each do |array_element|
28
25
  result += array_element.find_all_values_for(key) if array_element.is_a? Hash
@@ -42,9 +39,11 @@ class Hash
42
39
  each_value do |v|
43
40
  return true if v == value
44
41
  next unless v.is_a? Hash
42
+
45
43
  v.each_value do |v|
46
44
  return true if v == value
47
45
  next unless v.is_a? Hash
46
+
48
47
  v.each_value do |v|
49
48
  return true if v == value
50
49
  end
@@ -79,5 +78,4 @@ class Hash
79
78
  end
80
79
  end
81
80
  end
82
-
83
81
  end
@@ -82,4 +82,4 @@ end
82
82
  # Verify that the HTTP status code is 200..299 and that any defined mandatory elements / mandatory values are as expected
83
83
  Then 'it should be successful' do
84
84
  expect(current_exchange).to be_successful
85
- end
85
+ end
@@ -62,6 +62,7 @@ class Exchange
62
62
  # As a last resort this uses the global parameter. The handler should be set straight before an exchange is made to use this
63
63
  @exchange_handler ||= default_handler_used || Soaspec.api_handler
64
64
  raise '@exchange_handler not set. Set either with `Soaspec.api_handler = Handler.new` or within the exchange' unless @exchange_handler
65
+
65
66
  @fail_factory = nil
66
67
  @override_parameters = override_parameters
67
68
  @retry_for_success = false
@@ -91,6 +92,7 @@ class Exchange
91
92
  response = exchange_handler.make_request(request_params)
92
93
  return response unless retry_for_success?
93
94
  return response if (200..299).cover? @exchange_handler.status_code_for(response)
95
+
94
96
  sleep 0.5
95
97
  break response if count == retry_count
96
98
  end
@@ -109,6 +111,7 @@ class Exchange
109
111
  def retrieve(name)
110
112
  method = '__stored_val__' + name.to_s
111
113
  raise ArgumentError('Value not stored at ') unless exchange_handler.respond_to? method
114
+
112
115
  exchange_handler.send(method)
113
116
  end
114
117
 
@@ -230,4 +233,4 @@ class Exchange
230
233
  end
231
234
  self
232
235
  end
233
- end
236
+ end
@@ -1,8 +1,6 @@
1
-
2
1
  require_relative 'handler_accessors'
3
2
 
4
3
  module Soaspec
5
-
6
4
  # Inherit this for a class describing how to implement a particular exchange.
7
5
  # Has basic methods common for methods defining RSpec tests in YAML
8
6
  class ExchangeHandler
@@ -19,10 +17,11 @@ module Soaspec
19
17
  # Set instance variable name
20
18
  # @param [String, Symbol] name Name used when describing API test
21
19
  # @param [Hash] options Parameters defining handler. Used in descendants
22
- def initialize(name = self.class.to_s, options = {})
20
+ def initialize(name = self.class.to_s, _options = {})
23
21
  use
24
22
  @request_option = :hash
25
23
  raise ArgumentError, 'Cannot define both template_name and default_hash' if respond_to?(:template_name_value) && respond_to?(:default_hash_value)
24
+
26
25
  @template_name = respond_to?(:template_name_value) ? template_name_value : ''
27
26
  @default_hash = respond_to?(:default_hash_value) ? default_hash_value : {}
28
27
  @name = name
@@ -102,6 +101,7 @@ module Soaspec
102
101
  # Set instance variable and remove it from Hash
103
102
  def set_remove_key(hash, key)
104
103
  return unless hash.key? key
104
+
105
105
  __send__("#{key}=", hash[key])
106
106
  hash.delete key
107
107
  end
@@ -114,7 +114,8 @@ module Soaspec
114
114
  # Request of API call. Either intended request or actual request
115
115
  def request(response)
116
116
  return "Request not yet sent Request option is #{@request_option}" unless response
117
+
117
118
  'Specific API handler should implement this'
118
119
  end
119
120
  end
120
- end
121
+ end
@@ -2,7 +2,6 @@ module Soaspec
2
2
  # Describes methods test handlers use to easily set attributes
3
3
  # Some are included in 'success scenarios' and to configure the request sent
4
4
  module HandlerAccessors
5
-
6
5
  # Defines expected_mandatory_elements method used in 'success_scenario' shared examples
7
6
  # to indicate certain elements must be present
8
7
  # @param [Array] elements Array of symbols specifying expected element names for 'success scenario' in snakecase
@@ -22,6 +21,7 @@ module Soaspec
22
21
  def mandatory_elements(elements)
23
22
  define_method('expected_mandatory_elements') do
24
23
  return [elements] if elements.is_a?(String) || elements.is_a?(Symbol)
24
+
25
25
  elements
26
26
  end
27
27
  end
@@ -38,6 +38,7 @@ module Soaspec
38
38
  #
39
39
  def mandatory_xpath_values(xpath_value_pairs)
40
40
  raise ArgumentError('Hash of {xpath => expected values} expected ') unless xpath_value_pairs.is_a? Hash
41
+
41
42
  define_method('expected_mandatory_xpath_values') { xpath_value_pairs }
42
43
  end
43
44
 
@@ -53,6 +54,7 @@ module Soaspec
53
54
  #
54
55
  def mandatory_json_values(json_value_pairs)
55
56
  raise ArgumentError("Hash of {'jsonpath' => expected values} expected") unless json_value_pairs.is_a? Hash
57
+
56
58
  define_method('expected_mandatory_json_values') { json_value_pairs }
57
59
  end
58
60
 
@@ -73,7 +75,7 @@ module Soaspec
73
75
  # @param [String, Symbol] name Method name used to access attribute
74
76
  # @param [String, nil, Hash] attribute Attribute name to extract from xml. If not set, this will default to @name
75
77
  def attribute(name, attribute = nil)
76
- attribute_used = attribute ? attribute : name.to_s
78
+ attribute_used = attribute || name.to_s
77
79
  define_method("__custom_path_#{name}") do |response|
78
80
  value_from_path(response, 'implicit', attribute: attribute_used)
79
81
  end
@@ -83,6 +85,7 @@ module Soaspec
83
85
  # You must then use lower case in the xpath's to obtain the desired values
84
86
  def convert_to_lower(set)
85
87
  return unless set
88
+
86
89
  define_method('convert_to_lower?') { true }
87
90
  end
88
91
 
@@ -92,6 +95,7 @@ module Soaspec
92
95
  # This will be overridden if xpath has a ':' in it
93
96
  def strip_namespaces(set)
94
97
  return unless set
98
+
95
99
  # Whether to remove namespaces in xpath assertion automatically
96
100
  define_method('strip_namespaces?') { true }
97
101
  end
@@ -116,4 +120,4 @@ module Soaspec
116
120
  end
117
121
  end
118
122
  end
119
- end
123
+ end