soaspec 0.2.32 → 0.2.33

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -15
  3. data/.gitlab-ci.yml +62 -62
  4. data/.rspec +3 -3
  5. data/.rubocop.yml +2 -2
  6. data/CODE_OF_CONDUCT.md +74 -74
  7. data/ChangeLog +632 -625
  8. data/Dockerfile +7 -7
  9. data/Gemfile +8 -8
  10. data/LICENSE.txt +21 -21
  11. data/README.md +231 -231
  12. data/Rakefile +52 -52
  13. data/Todo.md +16 -16
  14. data/exe/soaspec +138 -138
  15. data/exe/xml_to_yaml_file +43 -43
  16. data/lib/soaspec.rb +106 -105
  17. data/lib/soaspec/baseline.rb +23 -0
  18. data/lib/soaspec/core_ext/hash.rb +44 -44
  19. data/lib/soaspec/cucumber/generic_steps.rb +94 -94
  20. data/lib/soaspec/demo.rb +6 -6
  21. data/lib/soaspec/errors.rb +24 -22
  22. data/lib/soaspec/exchange/exchange.rb +129 -129
  23. data/lib/soaspec/exchange/exchange_extractor.rb +90 -90
  24. data/lib/soaspec/exchange/exchange_properties.rb +28 -28
  25. data/lib/soaspec/exchange/exchange_repeater.rb +21 -21
  26. data/lib/soaspec/exchange/request_builder.rb +70 -70
  27. data/lib/soaspec/exchange/variable_storer.rb +24 -24
  28. data/lib/soaspec/exchange_handlers/exchange_handler.rb +98 -98
  29. data/lib/soaspec/exchange_handlers/exchange_handler_defaults.rb +61 -61
  30. data/lib/soaspec/exchange_handlers/handler_accessors.rb +132 -132
  31. data/lib/soaspec/exchange_handlers/request/rest_request.rb +59 -51
  32. data/lib/soaspec/exchange_handlers/request/soap_request.rb +41 -41
  33. data/lib/soaspec/exchange_handlers/response_extractor.rb +84 -84
  34. data/lib/soaspec/exchange_handlers/rest_exchanger_factory.rb +111 -111
  35. data/lib/soaspec/exchange_handlers/rest_handler.rb +307 -298
  36. data/lib/soaspec/exchange_handlers/rest_methods.rb +65 -65
  37. data/lib/soaspec/exchange_handlers/rest_parameters.rb +112 -112
  38. data/lib/soaspec/exchange_handlers/rest_parameters_defaults.rb +42 -42
  39. data/lib/soaspec/exchange_handlers/soap_handler.rb +241 -241
  40. data/lib/soaspec/exe_helpers.rb +94 -94
  41. data/lib/soaspec/generate_server.rb +48 -48
  42. data/lib/soaspec/generator/.rspec.erb +5 -5
  43. data/lib/soaspec/generator/.travis.yml.erb +5 -5
  44. data/lib/soaspec/generator/Gemfile.erb +8 -8
  45. data/lib/soaspec/generator/README.md.erb +29 -29
  46. data/lib/soaspec/generator/Rakefile.erb +19 -19
  47. data/lib/soaspec/generator/config/data/default.yml.erb +2 -2
  48. data/lib/soaspec/generator/css/bootstrap.css +6833 -6833
  49. data/lib/soaspec/generator/features/support/env.rb.erb +3 -3
  50. data/lib/soaspec/generator/generate_exchange.html.erb +47 -47
  51. data/lib/soaspec/generator/lib/blz_service.rb.erb +26 -26
  52. data/lib/soaspec/generator/lib/dynamic_class_content.rb.erb +12 -12
  53. data/lib/soaspec/generator/lib/new_rest_service.rb.erb +56 -56
  54. data/lib/soaspec/generator/lib/new_soap_service.rb.erb +29 -29
  55. data/lib/soaspec/generator/lib/package_service.rb.erb +2 -2
  56. data/lib/soaspec/generator/lib/shared_example.rb.erb +8 -8
  57. data/lib/soaspec/generator/spec/dynamic_soap_spec.rb.erb +12 -12
  58. data/lib/soaspec/generator/spec/rest_spec.rb.erb +9 -9
  59. data/lib/soaspec/generator/spec/soap_spec.rb.erb +51 -51
  60. data/lib/soaspec/generator/spec/spec_helper.rb.erb +23 -23
  61. data/lib/soaspec/generator/template/soap_template.xml +6 -6
  62. data/lib/soaspec/indifferent_hash.rb +9 -9
  63. data/lib/soaspec/interpreter.rb +70 -70
  64. data/lib/soaspec/matchers.rb +140 -118
  65. data/lib/soaspec/o_auth2.rb +142 -142
  66. data/lib/soaspec/soaspec_shared_examples.rb +26 -26
  67. data/lib/soaspec/spec_logger.rb +143 -143
  68. data/lib/soaspec/template_reader.rb +30 -30
  69. data/lib/soaspec/test_server/bank.wsdl +90 -90
  70. data/lib/soaspec/test_server/get_bank.rb +166 -166
  71. data/lib/soaspec/test_server/id_manager.rb +41 -41
  72. data/lib/soaspec/test_server/invoices.rb +29 -29
  73. data/lib/soaspec/test_server/namespace.xml +14 -14
  74. data/lib/soaspec/test_server/note.xml +5 -5
  75. data/lib/soaspec/test_server/puppy_service.rb +21 -21
  76. data/lib/soaspec/test_server/test_attribute.rb +14 -14
  77. data/lib/soaspec/test_server/test_namespace.rb +14 -14
  78. data/lib/soaspec/version.rb +6 -6
  79. data/lib/soaspec/virtual_server.rb +190 -176
  80. data/lib/soaspec/wait.rb +43 -43
  81. data/lib/soaspec/wsdl_generator.rb +215 -215
  82. data/soaspec.gemspec +58 -58
  83. data/test.wsdl +116 -116
  84. data/test.xml +10 -10
  85. data/test_wsdl.rb +43 -43
  86. metadata +4 -3
@@ -1,6 +1,6 @@
1
- # frozen_string_literal: true
2
-
3
- # Load this file for demoing Soaspec (e.g in IRB). Has common settings applicable for demoing
4
-
5
- require_relative '../soaspec'
6
- Soaspec::SpecLogger.output_to_terminal = true
1
+ # frozen_string_literal: true
2
+
3
+ # Load this file for demoing Soaspec (e.g in IRB). Has common settings applicable for demoing
4
+
5
+ require_relative '../soaspec'
6
+ Soaspec::SpecLogger.output_to_terminal = true
@@ -1,22 +1,24 @@
1
- # frozen_string_literal: true
2
-
3
- module Soaspec
4
- # Standard Error related to Soaspec
5
- class Error < StandardError; end
6
- # Error related to a response
7
- class ResponseError < StandardError; end
8
- end
9
-
10
- # Raised to represent when there's no element at an Xpath
11
- class NoElementAtPath < Soaspec::Error
12
- def initialize(msg = 'No element at path found')
13
- super
14
- end
15
- end
16
-
17
- # Did not find any element by provided key in the Hash
18
- class NoElementInHash < Soaspec::Error
19
- def initialize(msg = 'No element in Hash found')
20
- super
21
- end
22
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Soaspec
4
+ # Standard Error related to Soaspec
5
+ class Error < StandardError; end
6
+ # Error related to a response
7
+ class ResponseError < Error; end
8
+ # Error related to not having a recorded baseline yet
9
+ class BaselineError < Error; end
10
+ end
11
+
12
+ # Raised to represent when there's no element at an Xpath
13
+ class NoElementAtPath < Soaspec::Error
14
+ def initialize(msg = 'No element at path found')
15
+ super
16
+ end
17
+ end
18
+
19
+ # Did not find any element by provided key in the Hash
20
+ class NoElementInHash < Soaspec::Error
21
+ def initialize(msg = 'No element in Hash found')
22
+ super
23
+ end
24
+ end
@@ -1,129 +1,129 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../../soaspec'
4
- require_relative 'exchange_properties'
5
- require_relative 'exchange_extractor'
6
- require_relative 'request_builder'
7
- require_relative 'exchange_repeater'
8
- require_relative 'variable_storer'
9
-
10
- # This represents a request / response pair
11
- # Essentially, params in the exchange that are set are related to the request
12
- # What is returned is related to the response
13
- #
14
- # It is tied to an ExchangeHandler that needs to be defined either globally before it's created or in 'default_handler_used'
15
- class Exchange
16
- extend Soaspec::ExchangeProperties
17
- include Soaspec::ExchangeExtractor
18
- include Soaspec::RequestBuilder
19
- include Soaspec::ExchangeRepeater
20
- include Soaspec::VariableStorer
21
-
22
- # Instance of ExchangeHandler for which this exchange is made
23
- attr_accessor :exchange_handler
24
- # @return [Integer] How many times to retry for a success
25
- attr_accessor :retry_count
26
- # @return [Integer] Times request was retried before being returned
27
- attr_accessor :times_retried
28
- # @@return [String] Name used for displaying class
29
- attr_accessor :test_name
30
- # Expect Factory to fail upon trying to create
31
- attr_writer :fail_factory
32
- # Parameters to override for default params
33
- attr_accessor :override_parameters
34
-
35
- # Set retry for success variable to true so that request will be retried
36
- # for retry_count until it's true
37
- def retry_for_success
38
- @retry_for_success = true
39
- self
40
- end
41
-
42
- # This is set on an individual Exchange marking it as one that should be retried
43
- # @return [Bool] Whether to keep making request until success code reached
44
- def retry_for_success?
45
- @retry_for_success
46
- end
47
-
48
- # Defined as general rule from ExchangeHandler
49
- # @return [Boolean] Whether exception is an exception that must be retried
50
- def invalid_exception?
51
- !exchange_handler.retry_on_exceptions.find { |e| e == exchange_handler.exception.class }.nil?
52
- end
53
-
54
- # Override this in subclass to tie that subclass to an ExchangeHandler
55
- # @return [Soaspec::ExchangeHandler] Soaspec::ExchangeHandler used by this exchange
56
- def default_handler_used; end
57
-
58
- # Create new Exchange according to parameters set. A response will be made if called
59
- # explicitly with 'response' method or through other methods that use it like 'status_code'
60
- # @param [Symbol, String] name Name shown in RSpec run
61
- # @param [Hash] override_parameters Parameters to override for default params
62
- def initialize(name = self.class.to_s, override_parameters = {})
63
- self.test_name ||= name.to_s
64
- # As a last resort this uses the global parameter. The handler should be set straight before an exchange is made to use this
65
- @exchange_handler ||= default_handler_used || Soaspec.api_handler
66
- raise '@exchange_handler not set. Set either with `Soaspec.api_handler = Handler.new` or within the exchange' unless @exchange_handler
67
-
68
- @fail_factory = nil
69
- @override_parameters = override_parameters
70
- @retry_for_success = false
71
- self.retry_count = exchange_handler.retry_exception_limit
72
- exchange_handler.elements.each { |element| methods_for_element(element) }
73
- end
74
-
75
- # @return [Hash] Hash representing what will be sent
76
- def request_parameters
77
- exchange_handler.request_parameters(@override_parameters)
78
- end
79
-
80
- # Make request to handler with parameters defined
81
- # Will retry until success code reached if retry_for_success? is set
82
- # @return [Response] Response from Api handler
83
- def make_request
84
- Soaspec::SpecLogger.info 'Example ' + test_name
85
- request_params = @override_parameters
86
- (0..retry_count).each do |count|
87
- response = exchange_handler.make_request(request_params)
88
- return response if !retry_for_success? && !invalid_exception?
89
- return response if (200..299).cover? exchange_handler.status_code_for(response)
90
-
91
- sleep exchange_handler.retry_pause_time # Time before retrying
92
- self.times_retried = count
93
- break response if count == retry_count
94
- end
95
- end
96
-
97
- # Name describing this class when used with `RSpec.describe`
98
- # This will make the request and store the response
99
- # @return [String] Name given when initializing
100
- def to_s
101
- test_name
102
- end
103
-
104
- # @return [RestClient::Response,Savon::Response] Returns response object from Api.
105
- # Will make the request if not made and then cache it for later on
106
- # @example For SOAP it will be a Savon response
107
- # response.body (body of response as Hash)
108
- # response.header (head of response as Hash)
109
- # @example For REST it will be a RestClient::Response
110
- def response
111
- require 'forwardable'
112
- Soaspec.last_exchange = self
113
- @response ||= make_request
114
- @response.define_singleton_method(:exchange) { Soaspec.last_exchange } unless @response.respond_to?(:exchange)
115
- @response.extend Forwardable
116
- @response.delegate %i[value_from_path values_from_path] => :exchange
117
- @response
118
- end
119
-
120
- # @return [ResponseObject] Currently returning response object. This will change (in 0.3) to be itself to
121
- # allow easy method chaining
122
- def call
123
- if Soaspec.log_warnings
124
- warn 'This "call" method will be changed to return "Exchange" object in 0.3. ' \
125
- 'Use "response" method if you want the "response" object'
126
- end
127
- response
128
- end
129
- end
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../soaspec'
4
+ require_relative 'exchange_properties'
5
+ require_relative 'exchange_extractor'
6
+ require_relative 'request_builder'
7
+ require_relative 'exchange_repeater'
8
+ require_relative 'variable_storer'
9
+
10
+ # This represents a request / response pair
11
+ # Essentially, params in the exchange that are set are related to the request
12
+ # What is returned is related to the response
13
+ #
14
+ # It is tied to an ExchangeHandler that needs to be defined either globally before it's created or in 'default_handler_used'
15
+ class Exchange
16
+ extend Soaspec::ExchangeProperties
17
+ include Soaspec::ExchangeExtractor
18
+ include Soaspec::RequestBuilder
19
+ include Soaspec::ExchangeRepeater
20
+ include Soaspec::VariableStorer
21
+
22
+ # Instance of ExchangeHandler for which this exchange is made
23
+ attr_accessor :exchange_handler
24
+ # @return [Integer] How many times to retry for a success
25
+ attr_accessor :retry_count
26
+ # @return [Integer] Times request was retried before being returned
27
+ attr_accessor :times_retried
28
+ # @@return [String] Name used for displaying class
29
+ attr_accessor :test_name
30
+ # Expect Factory to fail upon trying to create
31
+ attr_writer :fail_factory
32
+ # Parameters to override for default params
33
+ attr_accessor :override_parameters
34
+
35
+ # Set retry for success variable to true so that request will be retried
36
+ # for retry_count until it's true
37
+ def retry_for_success
38
+ @retry_for_success = true
39
+ self
40
+ end
41
+
42
+ # This is set on an individual Exchange marking it as one that should be retried
43
+ # @return [Bool] Whether to keep making request until success code reached
44
+ def retry_for_success?
45
+ @retry_for_success
46
+ end
47
+
48
+ # Defined as general rule from ExchangeHandler
49
+ # @return [Boolean] Whether exception is an exception that must be retried
50
+ def invalid_exception?
51
+ !exchange_handler.retry_on_exceptions.find { |e| e == exchange_handler.exception.class }.nil?
52
+ end
53
+
54
+ # Override this in subclass to tie that subclass to an ExchangeHandler
55
+ # @return [Soaspec::ExchangeHandler] Soaspec::ExchangeHandler used by this exchange
56
+ def default_handler_used; end
57
+
58
+ # Create new Exchange according to parameters set. A response will be made if called
59
+ # explicitly with 'response' method or through other methods that use it like 'status_code'
60
+ # @param [Symbol, String] name Name shown in RSpec run
61
+ # @param [Hash] override_parameters Parameters to override for default params
62
+ def initialize(name = self.class.to_s, override_parameters = {})
63
+ self.test_name ||= name.to_s
64
+ # As a last resort this uses the global parameter. The handler should be set straight before an exchange is made to use this
65
+ @exchange_handler ||= default_handler_used || Soaspec.api_handler
66
+ raise '@exchange_handler not set. Set either with `Soaspec.api_handler = Handler.new` or within the exchange' unless @exchange_handler
67
+
68
+ @fail_factory = nil
69
+ @override_parameters = override_parameters
70
+ @retry_for_success = false
71
+ self.retry_count = exchange_handler.retry_exception_limit
72
+ exchange_handler.elements.each { |element| methods_for_element(element) }
73
+ end
74
+
75
+ # @return [Hash] Hash representing what will be sent
76
+ def request_parameters
77
+ exchange_handler.request_parameters(@override_parameters)
78
+ end
79
+
80
+ # Make request to handler with parameters defined
81
+ # Will retry until success code reached if retry_for_success? is set
82
+ # @return [Response] Response from Api handler
83
+ def make_request
84
+ Soaspec::SpecLogger.info 'Example ' + test_name
85
+ request_params = @override_parameters
86
+ (0..retry_count).each do |count|
87
+ response = exchange_handler.make_request(request_params)
88
+ return response if !retry_for_success? && !invalid_exception?
89
+ return response if (200..299).cover? exchange_handler.status_code_for(response)
90
+
91
+ sleep exchange_handler.retry_pause_time # Time before retrying
92
+ self.times_retried = count
93
+ break response if count == retry_count
94
+ end
95
+ end
96
+
97
+ # Name describing this class when used with `RSpec.describe`
98
+ # This will make the request and store the response
99
+ # @return [String] Name given when initializing
100
+ def to_s
101
+ test_name
102
+ end
103
+
104
+ # @return [RestClient::Response,Savon::Response] Returns response object from Api.
105
+ # Will make the request if not made and then cache it for later on
106
+ # @example For SOAP it will be a Savon response
107
+ # response.body (body of response as Hash)
108
+ # response.header (head of response as Hash)
109
+ # @example For REST it will be a RestClient::Response
110
+ def response
111
+ require 'forwardable'
112
+ Soaspec.last_exchange = self
113
+ @response ||= make_request
114
+ @response.define_singleton_method(:exchange) { Soaspec.last_exchange } unless @response.respond_to?(:exchange)
115
+ @response.extend Forwardable
116
+ @response.delegate %i[value_from_path values_from_path] => :exchange
117
+ @response
118
+ end
119
+
120
+ # @return [ResponseObject] Currently returning response object. This will change (in 0.3) to be itself to
121
+ # allow easy method chaining
122
+ def call
123
+ if Soaspec.log_warnings
124
+ warn 'This "call" method will be changed to return "Exchange" object in 0.3. ' \
125
+ 'Use "response" method if you want the "response" object'
126
+ end
127
+ response
128
+ end
129
+ end
@@ -1,90 +1,90 @@
1
- # frozen_string_literal: true
2
-
3
- module Soaspec
4
- # Methods for extracting aspects of the traffic for a request / response
5
- # in an exchange from the ExchangeHandler that it's tied to
6
- module ExchangeExtractor
7
- # Request of API call. Either intended request or actual request
8
- # @return [Object] Object representing request of API
9
- def request
10
- exchange_handler.request(@response)
11
- end
12
-
13
- # Get status code from api class. This is http response code for Web Api
14
- # @return [Integer] Status code from api class
15
- def status_code
16
- exchange_handler.status_code_for(response)
17
- end
18
-
19
- # @return [Boolean] Whether Api success code is successful
20
- def successful_status_code?
21
- (200..299).cover? status_code
22
- end
23
-
24
- # Extract value from path api class
25
- # @example Extract unique value
26
- # @exchange['unique_value_name']
27
- # @example Extract value via JSON path
28
- # @exchange['$..path.to.element']
29
- # @example Extract value via XPath
30
- # @exchange['//path/to/element']
31
- # @param [Object] path Path to return element for api class E.g - for SOAP this is XPath string. For JSON, this is Hash dig Array
32
- # @return [String] Value at path
33
- def [](path)
34
- exchange_handler.value_from_path(response, path.to_s)
35
- end
36
-
37
- alias value_from_path []
38
-
39
- # Using same path syntax as []. Returns true of false depending on whether an element is found
40
- # @return [Boolean] Whether an element exists at the path
41
- def element?(path)
42
- self[path]
43
- true
44
- rescue NoElementAtPath
45
- false
46
- end
47
-
48
- # @example Counting items in a JSON list
49
- # # Say there is JSON response {"notes":[{"title":"note1","note":"A note"},{"title":"note2"}]}
50
- # titles = @exchange.values_at_path('$..title')
51
- # expect(titles.count).to eq 2
52
- # expect(titles.first).to eq 'note1'
53
- # @param [String] path XPath, JSONPath to extract value
54
- # @param [String] attribute Attribute to obtain from XML element
55
- # @return [Array] List of values found at path
56
- def values_from_path(path, attribute: nil)
57
- exchange_handler.values_from_path(response, path, attribute: attribute)
58
- end
59
-
60
- # Return the response equivalent of the response. XML, JSON will be converted to a Hash
61
- # @example Counting items in a JSON list
62
- # # Say there is JSON response {"notes":[{"title":"note1","note":"A note"},{"title":"note2"}]}
63
- # hash = @exchange.to_hash
64
- # expect(hash['notes'].count).to eq 2
65
- # expect(hash['notes'].first['title']).to eq 'note1'
66
- # @return [Hash] Hash representing the response of the API
67
- def to_hash
68
- exchange_handler.to_hash(response)
69
- end
70
-
71
- private
72
-
73
- # Used to define methods on an exchange based on what's defined by the ExchangeHandler's methods
74
- # @param [String] element Element to define methods for
75
- def methods_for_element(element)
76
- element_name = element.to_s.split('__custom_path_').last
77
- define_singleton_method(element_name) do
78
- exchange_handler.__send__(element, response) # Forward the call onto handler to retrieve the element for the response
79
- end
80
- define_singleton_method("#{element_name}?") do
81
- begin
82
- __send__ element_name
83
- true
84
- rescue NoElementAtPath
85
- false
86
- end
87
- end
88
- end
89
- end
90
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Soaspec
4
+ # Methods for extracting aspects of the traffic for a request / response
5
+ # in an exchange from the ExchangeHandler that it's tied to
6
+ module ExchangeExtractor
7
+ # Request of API call. Either intended request or actual request
8
+ # @return [Object] Object representing request of API
9
+ def request
10
+ exchange_handler.request(@response)
11
+ end
12
+
13
+ # Get status code from api class. This is http response code for Web Api
14
+ # @return [Integer] Status code from api class
15
+ def status_code
16
+ exchange_handler.status_code_for(response)
17
+ end
18
+
19
+ # @return [Boolean] Whether Api success code is successful
20
+ def successful_status_code?
21
+ (200..299).cover? status_code
22
+ end
23
+
24
+ # Extract value from path api class
25
+ # @example Extract unique value
26
+ # @exchange['unique_value_name']
27
+ # @example Extract value via JSON path
28
+ # @exchange['$..path.to.element']
29
+ # @example Extract value via XPath
30
+ # @exchange['//path/to/element']
31
+ # @param [Object] path Path to return element for api class E.g - for SOAP this is XPath string. For JSON, this is Hash dig Array
32
+ # @return [String] Value at path
33
+ def [](path)
34
+ exchange_handler.value_from_path(response, path.to_s)
35
+ end
36
+
37
+ alias value_from_path []
38
+
39
+ # Using same path syntax as []. Returns true of false depending on whether an element is found
40
+ # @return [Boolean] Whether an element exists at the path
41
+ def element?(path)
42
+ self[path]
43
+ true
44
+ rescue NoElementAtPath
45
+ false
46
+ end
47
+
48
+ # @example Counting items in a JSON list
49
+ # # Say there is JSON response {"notes":[{"title":"note1","note":"A note"},{"title":"note2"}]}
50
+ # titles = @exchange.values_at_path('$..title')
51
+ # expect(titles.count).to eq 2
52
+ # expect(titles.first).to eq 'note1'
53
+ # @param [String] path XPath, JSONPath to extract value
54
+ # @param [String] attribute Attribute to obtain from XML element
55
+ # @return [Array] List of values found at path
56
+ def values_from_path(path, attribute: nil)
57
+ exchange_handler.values_from_path(response, path, attribute: attribute)
58
+ end
59
+
60
+ # Return the response equivalent of the response. XML, JSON will be converted to a Hash
61
+ # @example Counting items in a JSON list
62
+ # # Say there is JSON response {"notes":[{"title":"note1","note":"A note"},{"title":"note2"}]}
63
+ # hash = @exchange.to_hash
64
+ # expect(hash['notes'].count).to eq 2
65
+ # expect(hash['notes'].first['title']).to eq 'note1'
66
+ # @return [Hash] Hash representing the response of the API
67
+ def to_hash
68
+ exchange_handler.to_hash(response)
69
+ end
70
+
71
+ private
72
+
73
+ # Used to define methods on an exchange based on what's defined by the ExchangeHandler's methods
74
+ # @param [String] element Element to define methods for
75
+ def methods_for_element(element)
76
+ element_name = element.to_s.split('__custom_path_').last
77
+ define_singleton_method(element_name) do
78
+ exchange_handler.__send__(element, response) # Forward the call onto handler to retrieve the element for the response
79
+ end
80
+ define_singleton_method("#{element_name}?") do
81
+ begin
82
+ __send__ element_name
83
+ true
84
+ rescue NoElementAtPath
85
+ false
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end