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 |