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
177 178 179 180 181 182 183 184 |
# File 'lib/soaspec/wsdl_generator.rb', line 177 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.
109 110 111 |
# File 'lib/soaspec/wsdl_generator.rb', line 109 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.
103 104 105 |
# File 'lib/soaspec/wsdl_generator.rb', line 103 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
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/soaspec/wsdl_generator.rb', line 146 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
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/soaspec/wsdl_generator.rb', line 198 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.
68 69 70 71 72 |
# File 'lib/soaspec/wsdl_generator.rb', line 68 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
90 91 92 93 94 95 96 97 98 99 |
# File 'lib/soaspec/wsdl_generator.rb', line 90 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 |
# File 'lib/soaspec/wsdl_generator.rb', line 9 def generate_from_wsdl() auth_name, auth_password = enter_auth_details if [:auth] == 'basic' @virtual = false = { wsdl: [:wsdl] } [:basic_auth] = [auth_name, auth_password] if [:auth] == 'basic' 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.
76 77 78 |
# File 'lib/soaspec/wsdl_generator.rb', line 76 def name_after_namespace(element) value_after_namespace(element.name) end |
#name_of_wsdl ⇒ Object
Prompt user for Service name for wsdl
187 188 189 190 191 192 193 194 |
# File 'lib/soaspec/wsdl_generator.rb', line 187 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
115 116 117 118 119 120 |
# File 'lib/soaspec/wsdl_generator.rb', line 115 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
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/soaspec/wsdl_generator.rb', line 125 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
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/soaspec/wsdl_generator.rb', line 49 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
83 84 85 |
# File 'lib/soaspec/wsdl_generator.rb', line 83 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
170 171 172 173 174 |
# File 'lib/soaspec/wsdl_generator.rb', line 170 def wsdl_to_yaml_for(list) raise "'@content' string must be set" if @content.nil? list.each { |element| document_type_for element } end |