Module: Soaspec::WsdlGenerator
- Includes:
- ExeHelpers
- Defined in:
- lib/soaspec/wsdl_generator.rb
Overview
Produce test content from a WSDL
Instance Method Summary collapse
-
#ask_wsdl ⇒ Object
Prompt user for wsdl.
-
#camel_case(underscore_separated) ⇒ String
CamelCased value.
-
#complex_type?(element) ⇒ Boolean
True if Nokogiri element is a complex type, that is, has a complexType element underneath itself.
-
#document_type_for(element, depth = 1) ⇒ Object
Adds documentation content for all children of XML element This will be an example yaml for setting SOAP requests.
-
#enter_auth_details ⇒ Array
Prompt user to enter basic auth details.
-
#enumeration?(type) ⇒ Boolean
Whether WSDL type is an enumeration.
-
#fill_in_field_from_type(type) ⇒ Object
Based on WSDL type return a valid value.
-
#generate_from_wsdl(options) ⇒ Object
Generate from WSDL.
-
#name_after_namespace(element) ⇒ String
Name of element excluding namespace.
-
#name_of_wsdl ⇒ Object
Prompt user for Service name for wsdl.
-
#root_element_for(op_details) ⇒ Object
Element at the root of an operation.
-
#root_elements_for(op_details) ⇒ Nokogiri::XML::NodeSet
Returns list of elements present at the root of an operation.
-
#try_enum_for(type) ⇒ Object
Attempt to calculate values of enumeration by looking up type in Schema.
-
#value_after_namespace(string) ⇒ String
Return value of string after a namespace.
-
#wsdl_to_yaml_for(list) ⇒ Object
Makes a yaml string in a ‘@content’ instance variable.
Methods included from ExeHelpers
#class_content, #create_file, #create_files, #create_files_for, #create_folder, #generated_soap_spec_for, #retrieve_contents, #spec_task
Instance Method Details
#ask_wsdl ⇒ Object
Prompt user for wsdl
179 180 181 182 183 184 185 186 |
# File 'lib/soaspec/wsdl_generator.rb', line 179 def ask_wsdl prompt = <<-WSDL_LOC Enter WSDL: WSDL_LOC print prompt.chop @wsdl = $stdin.gets.strip puts end |
#camel_case(underscore_separated) ⇒ String
Returns CamelCased value.
111 112 113 |
# File 'lib/soaspec/wsdl_generator.rb', line 111 def camel_case(underscore_separated) underscore_separated.to_s.split('_').collect(&:capitalize).join end |
#complex_type?(element) ⇒ Boolean
Returns True if Nokogiri element is a complex type, that is, has a complexType element underneath itself.
105 106 107 |
# File 'lib/soaspec/wsdl_generator.rb', line 105 def complex_type?(element) element.children.any? { |child| name_after_namespace(child) == 'complexType' } end |
#document_type_for(element, depth = 1) ⇒ Object
Adds documentation content for all children of XML element This will be an example yaml for setting SOAP requests
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/soaspec/wsdl_generator.rb', line 148 def document_type_for(element, depth = 1) # raise "Too far deep for #{element}" unless depth < 6 return unless depth < 6 if complex_type? element complex_type = element.children.find { |c| name_after_namespace(c) == 'complexType' } sequence = complex_type.children.find { |c| name_after_namespace(c) == 'sequence' } sequence.children.select { |node| node.class == Nokogiri::XML::Element }.each do |sub_element| document_type_for sub_element, depth + 1 end else return "No type seen for #{element}, #{element.class}" unless element['type'] name = element['name'] type = value_after_namespace(element['type']) @use_camel_case = true unless /[[:upper:]]/.match(name[0]).nil? spaces = ' ' * depth @content += "#{spaces}#{name.snakecase}: #{fill_in_field_from_type(type)} # #{type} \n" end end |
#enter_auth_details ⇒ Array
Prompt user to enter basic auth details
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/soaspec/wsdl_generator.rb', line 200 def enter_auth_details prompt = <<-AUTH_PROMPT User Name: AUTH_PROMPT print prompt.chop auth_name = $stdin.gets.strip puts prompt = <<-PASSWORD User Password: PASSWORD print prompt.chop auth_password = $stdin.gets.strip puts [auth_name, auth_password] end |
#enumeration?(type) ⇒ Boolean
Returns Whether WSDL type is an enumeration.
70 71 72 73 74 |
# File 'lib/soaspec/wsdl_generator.rb', line 70 def enumeration?(type) return false unless type.first !type.xpath("*/#{type.first.namespace.prefix}:enumeration").empty? end |
#fill_in_field_from_type(type) ⇒ Object
Based on WSDL type return a valid value
92 93 94 95 96 97 98 99 100 101 |
# File 'lib/soaspec/wsdl_generator.rb', line 92 def fill_in_field_from_type(type) case type when 'string' then [:string_default] # 'test string' when 'int' then 2 when 'boolean' then true when 'double' then '1.5' else try_enum_for type end end |
#generate_from_wsdl(options) ⇒ Object
Generate from WSDL
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/soaspec/wsdl_generator.rb', line 9 def generate_from_wsdl() if [:auth] == 'basic' auth_name, auth_password = enter_auth_details [:basic_auth] = [auth_name, auth_password] end @virtual = false = { wsdl: [:wsdl] } wsdl_doc = Savon.client(**).wsdl @wsdl_schemas = wsdl_doc.parser.schemas # Create basic project files create_files %w[Rakefile Gemfile README.md spec/spec_helper.rb], ignore_if_present: true create_file(filename: '.rspec') create_file(filename: '.travis.yml') if [:ci] == 'travis' create_folder 'logs' create_file filename: "lib/#{[:name].snakecase}.rb", content: class_content # Files according to WSDL wsdl_doc.operations.each do |operation, op_details| puts "Creating files for operation: #{operation}" @content = "default:\n" @use_camel_case = false puts 'Message params: ' + op_details.to_s # From namespace identifier, find namespace, and for that find schemaLocation xsd and use that to build request op_details[:parameters]&.each do |element, details| @use_camel_case = true unless /[[:upper:]]/.match(element.to_s[0]).nil? @content += " #{element.to_s.snakecase}: #{fill_in_field_from_type(details[:type])} # #{details[:type]} \n" # TODO: If details is a Hash need to loop again end wsdl_to_yaml_for root_elements_for(op_details) params = [] params << 'convert_request_keys_to: :camelcase' if @use_camel_case params_string = params == [] ? '' : ', ' + params.join(', ') @class_params = "'#{camel_case(operation)}'#{params_string}" create_file(filename: "config/data/#{operation}.yml", content: @content) create_file(filename: "spec/#{operation}_spec.rb", content: generated_soap_spec_for(operation)) end end |
#name_after_namespace(element) ⇒ String
Returns Name of element excluding namespace.
78 79 80 |
# File 'lib/soaspec/wsdl_generator.rb', line 78 def name_after_namespace(element) value_after_namespace(element.name) end |
#name_of_wsdl ⇒ Object
Prompt user for Service name for wsdl
189 190 191 192 193 194 195 196 |
# File 'lib/soaspec/wsdl_generator.rb', line 189 def name_of_wsdl prompt = <<-WSDL_NAME Enter what you would like to name WSDL (CamelCase): WSDL_NAME print prompt.chop @name = $stdin.gets.strip puts end |
#root_element_for(op_details) ⇒ Object
Element at the root of an operation
117 118 119 120 121 122 |
# File 'lib/soaspec/wsdl_generator.rb', line 117 def root_element_for(op_details) root_element = @wsdl_schemas.at_xpath("//*[@name='#{op_details[:input]}']") raise 'Operation has no input defined' if root_element.nil? root_element end |
#root_elements_for(op_details) ⇒ Nokogiri::XML::NodeSet
Returns list of elements present at the root of an operation
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/soaspec/wsdl_generator.rb', line 127 def root_elements_for(op_details) raise "'@wsdl_schemas' must be defined" if @wsdl_schemas.nil? root_element = root_element_for(op_details) schema_namespace = root_element.namespace.prefix root_type = root_element['type'] if root_type @wsdl_schemas.xpath("//*[@name='#{value_after_namespace(root_type)}']//#{schema_namespace}:element") else return [] unless complex_type? root_element # Empty Array if there are no root elements complex_type = root_element.children.find { |c| c.name == 'complexType' } sequence = complex_type.children.find { |c| c.name == 'sequence' } sequence.xpath("#{schema_namespace}:element") end end |
#try_enum_for(type) ⇒ Object
Attempt to calculate values of enumeration by looking up type in Schema
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/soaspec/wsdl_generator.rb', line 51 def try_enum_for(type) raise "'@wsdl_schemas' must be defined" if @wsdl_schemas.nil? custom_type = @wsdl_schemas.xpath("//*[@name='#{type}']") if enumeration? custom_type prefix = custom_type.first.namespace.prefix enumerations = custom_type.xpath("//#{prefix}:enumeration") return 'Custom Type' if enumerations.empty? @enums_values = [] enumerations.each { |enum_value| @enums_values << "'#{enum_value['value']}'" } "~randomize [#{@enums_values.join(', ')}]" else 'Custom Type' end end |
#value_after_namespace(string) ⇒ String
Return value of string after a namespace
85 86 87 |
# File 'lib/soaspec/wsdl_generator.rb', line 85 def value_after_namespace(string) string.split(':').last end |
#wsdl_to_yaml_for(list) ⇒ Object
This should return YAML rather than just set an instance variable
Makes a yaml string in a ‘@content’ instance variable
172 173 174 175 176 |
# File 'lib/soaspec/wsdl_generator.rb', line 172 def wsdl_to_yaml_for(list) raise "'@content' string must be set" if @content.nil? list.each { |element| document_type_for element } end |