soaspec 0.2.24 → 0.2.25

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +15 -15
  3. data/.gitlab-ci.yml +51 -33
  4. data/.rspec +3 -3
  5. data/.rubocop.yml +2 -2
  6. data/CODE_OF_CONDUCT.md +74 -74
  7. data/ChangeLog +588 -577
  8. data/Gemfile +6 -6
  9. data/LICENSE.txt +21 -21
  10. data/README.md +230 -230
  11. data/Rakefile +50 -42
  12. data/Todo.md +15 -15
  13. data/exe/soaspec +137 -123
  14. data/exe/xml_to_yaml_file +42 -42
  15. data/lib/soaspec.rb +103 -101
  16. data/lib/soaspec/core_ext/hash.rb +42 -35
  17. data/lib/soaspec/cucumber/generic_steps.rb +85 -85
  18. data/lib/soaspec/demo.rb +4 -4
  19. data/lib/soaspec/exchange/exchange.rb +117 -111
  20. data/lib/soaspec/exchange/exchange_extractor.rb +83 -83
  21. data/lib/soaspec/exchange/exchange_properties.rb +26 -26
  22. data/lib/soaspec/exchange/exchange_repeater.rb +19 -19
  23. data/lib/soaspec/exchange/request_builder.rb +68 -68
  24. data/lib/soaspec/exchange/variable_storer.rb +22 -22
  25. data/lib/soaspec/exchange_handlers/exchange_handler.rb +130 -126
  26. data/lib/soaspec/exchange_handlers/handler_accessors.rb +130 -130
  27. data/lib/soaspec/exchange_handlers/request/rest_request.rb +49 -0
  28. data/lib/soaspec/exchange_handlers/request/soap_request.rb +39 -0
  29. data/lib/soaspec/exchange_handlers/response_extractor.rb +82 -82
  30. data/lib/soaspec/exchange_handlers/rest_exchanger_factory.rb +109 -109
  31. data/lib/soaspec/exchange_handlers/rest_handler.rb +287 -259
  32. data/lib/soaspec/exchange_handlers/rest_methods.rb +63 -44
  33. data/lib/soaspec/exchange_handlers/rest_parameters.rb +90 -86
  34. data/lib/soaspec/exchange_handlers/rest_parameters_defaults.rb +40 -21
  35. data/lib/soaspec/exchange_handlers/soap_handler.rb +239 -235
  36. data/lib/soaspec/exe_helpers.rb +92 -92
  37. data/lib/soaspec/generate_server.rb +46 -37
  38. data/lib/soaspec/generator/.rspec.erb +5 -5
  39. data/lib/soaspec/generator/.travis.yml.erb +5 -5
  40. data/lib/soaspec/generator/Gemfile.erb +8 -8
  41. data/lib/soaspec/generator/README.md.erb +29 -29
  42. data/lib/soaspec/generator/Rakefile.erb +19 -19
  43. data/lib/soaspec/generator/config/data/default.yml.erb +2 -2
  44. data/lib/soaspec/generator/css/bootstrap.css +6833 -6833
  45. data/lib/soaspec/generator/features/support/env.rb.erb +3 -0
  46. data/lib/soaspec/generator/generate_exchange.html.erb +47 -35
  47. data/lib/soaspec/generator/lib/blz_service.rb.erb +26 -26
  48. data/lib/soaspec/generator/lib/dynamic_class_content.rb.erb +12 -12
  49. data/lib/soaspec/generator/lib/new_rest_service.rb.erb +56 -51
  50. data/lib/soaspec/generator/lib/new_soap_service.rb.erb +29 -29
  51. data/lib/soaspec/generator/lib/package_service.rb.erb +2 -2
  52. data/lib/soaspec/generator/lib/shared_example.rb.erb +8 -8
  53. data/lib/soaspec/generator/spec/dynamic_soap_spec.rb.erb +12 -12
  54. data/lib/soaspec/generator/spec/rest_spec.rb.erb +9 -9
  55. data/lib/soaspec/generator/spec/soap_spec.rb.erb +51 -51
  56. data/lib/soaspec/generator/spec/spec_helper.rb.erb +23 -23
  57. data/lib/soaspec/generator/template/soap_template.xml +6 -6
  58. data/lib/soaspec/indifferent_hash.rb +7 -7
  59. data/lib/soaspec/interpreter.rb +39 -39
  60. data/lib/soaspec/matchers.rb +114 -114
  61. data/lib/soaspec/not_found_errors.rb +13 -13
  62. data/lib/soaspec/o_auth2.rb +128 -128
  63. data/lib/soaspec/soaspec_shared_examples.rb +24 -24
  64. data/lib/soaspec/spec_logger.rb +122 -121
  65. data/lib/soaspec/template_reader.rb +28 -28
  66. data/lib/soaspec/test_server/bank.wsdl +90 -90
  67. data/lib/soaspec/test_server/get_bank.rb +164 -164
  68. data/lib/soaspec/test_server/id_manager.rb +39 -39
  69. data/lib/soaspec/test_server/invoices.rb +27 -27
  70. data/lib/soaspec/test_server/namespace.xml +14 -14
  71. data/lib/soaspec/test_server/note.xml +5 -5
  72. data/lib/soaspec/test_server/puppy_service.rb +19 -19
  73. data/lib/soaspec/test_server/test_attribute.rb +12 -12
  74. data/lib/soaspec/test_server/test_namespace.rb +12 -12
  75. data/lib/soaspec/version.rb +4 -4
  76. data/lib/soaspec/virtual_server.rb +174 -174
  77. data/lib/soaspec/wait.rb +41 -41
  78. data/lib/soaspec/wsdl_generator.rb +215 -215
  79. data/soaspec.gemspec +56 -53
  80. data/test.wsdl +116 -116
  81. data/test.xml +10 -10
  82. data/test_wsdl.rb +41 -41
  83. metadata +38 -6
data/Rakefile CHANGED
@@ -1,42 +1,50 @@
1
- require 'bundler/gem_tasks'
2
- require 'rspec/core/rake_task'
3
- require 'rake/clean'
4
- require 'yard'
5
-
6
- ENV['folder'] ||= ''
7
- ENV['test'] ||= ''
8
-
9
- desc 'Run tests'
10
- RSpec::Core::RakeTask.new(spec: %i[clean clobber start_test_server]) do |t|
11
- t.pattern = "spec/**/#{ENV['folder']}*/#{ENV['test']}*_spec.rb"
12
- end
13
-
14
- task :parallel => [:clean, :clobber, :start_test_server] do
15
- puts `parallel_rspec spec`
16
- end
17
-
18
- task default: :spec
19
-
20
- CLEAN.include 'tmp/*'
21
- CLOBBER.include 'logs/*'
22
-
23
- desc 'Start virtual web service'
24
- task :start_test_server do
25
- ENV['leave_server_running'] = 'true' # This will stop created suites from killing this service
26
- mkdir_p 'logs'
27
- ENV['test_server_pid'] = Process.spawn('ruby', 'exe/soaspec', 'virtual_server', err: %w[logs/test_server.log w]).to_s
28
- sleep 2 # Wait a little for virtual server to start up
29
- puts 'Running test server at pid ' + ENV['test_server_pid']
30
- end
31
-
32
- YARD::Rake::YardocTask.new do |t|
33
- t.files = %w[features/**/*.feature features/**/*.rb lib/soaspec/cucumber/*.rb] # lib/soaspec/cucumber/*.rb]
34
- end
35
-
36
- desc 'Ensure system has all docs'
37
- task :must_have_docs do
38
- yard = `yard`
39
- puts yard
40
- percentage = yard.lines.last.strip.split('%').first.to_f
41
- raise 'Must be fully documented' unless percentage == 100.00
42
- end
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rake/clean'
4
+ require 'yard'
5
+ require 'yard/doctest/rake'
6
+
7
+ ENV['folder'] ||= ''
8
+ ENV['test'] ||= ''
9
+
10
+ desc 'Run tests'
11
+ RSpec::Core::RakeTask.new(spec: %i[clean clobber start_test_server]) do |t|
12
+ t.pattern = "spec/**/#{ENV['folder']}*/#{ENV['test']}*_spec.rb"
13
+ end
14
+
15
+ task :parallel => [:clean, :clobber, :start_test_server] do
16
+ puts `parallel_rspec spec`
17
+ end
18
+
19
+ task default: :spec
20
+
21
+ CLEAN.include 'tmp/*'
22
+ CLOBBER.include 'logs/*'
23
+
24
+ desc 'Start virtual web service'
25
+ task :start_test_server do
26
+ ENV['leave_server_running'] = 'true' # This will stop created suites from killing this service
27
+ mkdir_p 'logs'
28
+ ENV['test_server_pid'] = Process.spawn('ruby', 'exe/soaspec', 'virtual_server', err: %w[logs/test_server.log w]).to_s
29
+ sleep 2 # Wait a little for virtual server to start up
30
+ puts 'Running test server at pid ' + ENV['test_server_pid']
31
+ end
32
+
33
+ YARD::Rake::YardocTask.new do |t|
34
+ t.files = %w[features/**/*.feature features/**/*.rb lib/soaspec/cucumber/*.rb] # lib/soaspec/cucumber/*.rb]
35
+ end
36
+
37
+ desc 'Ensure system has all docs'
38
+ task :must_have_docs do
39
+ yard = `yard`
40
+ puts yard
41
+ percentage = yard.lines.last.strip.split('%').first.to_f
42
+ raise 'Must be fully documented' unless percentage == 100.00
43
+ end
44
+
45
+ desc 'Test examples shown in documentation'
46
+ YARD::Doctest::RakeTask.new do |task|
47
+ task.doctest_opts = %w[-v]
48
+ # task.pattern = 'lib/**/*.rb'
49
+ task.pattern = 'lib/soaspec/core_ext/hash.rb'
50
+ end
data/Todo.md CHANGED
@@ -1,15 +1,15 @@
1
- * `yard` should show everything documented
2
- * Rubocop should have 0 offenses
3
- * Unit tests
4
- * OAuth class, etc
5
- * Get initial `soaspec new` working with TODOs as placeholders for how to get started
6
- * Request method from within exchange
7
- * Use this in tests
8
- * Basic service generator
9
- * Give examples and convenience methods for building classes for each SOAP or REST operation
10
- * Potentially have in built use of 'vcr' and 'http_stub' gems
11
- * Handle proxies to record traffic for MiddleWare testing
12
- * soaspec generate
13
- * Get wsdl generator working for non complex gems (Put on hold til new Savon version)
14
- * Generate from a RAML
15
- * Much more - please raise an issue for suggestion
1
+ * `yard` should show everything documented
2
+ * Rubocop should have 0 offenses
3
+ * Unit tests
4
+ * OAuth class, etc
5
+ * Get initial `soaspec new` working with TODOs as placeholders for how to get started
6
+ * Request method from within exchange
7
+ * Use this in tests
8
+ * Basic service generator
9
+ * Give examples and convenience methods for building classes for each SOAP or REST operation
10
+ * Potentially have in built use of 'vcr' and 'http_stub' gems
11
+ * Handle proxies to record traffic for MiddleWare testing
12
+ * soaspec generate
13
+ * Get wsdl generator working for non complex gems (Put on hold til new Savon version)
14
+ * Generate from a RAML
15
+ * Much more - please raise an issue for suggestion
data/exe/soaspec CHANGED
@@ -1,123 +1,137 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'thor'
4
- $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
5
- require 'savon'
6
- require 'soaspec'
7
- require 'soaspec/virtual_server'
8
- require 'soaspec/wsdl_generator'
9
-
10
- module Soaspec
11
- # Common executable for Soaspec
12
- class Exe < Thor
13
- include Soaspec::ExeHelpers
14
- include Soaspec::WsdlGenerator
15
-
16
- long_desc <<-LONGDESC
17
- `soaspec new` will generate the initial files and folders for starting a testing project using soaspec
18
- \x5
19
-
20
- `soaspec new soap` will create example files testing against a SOAP service
21
- \x5
22
-
23
- `soaspec new rest` will create example files testing against a REST service
24
- LONGDESC
25
- desc 'new [type]', 'Initialize soaspec repository'
26
- option :ci, default: 'jenkins', banner: 'What Continuous Integration is used'
27
- option :virtual, type: :boolean, default: true, banner: 'Whether to set things up for a virtual server'
28
- def new(type = 'initial')
29
- @virtual = options[:virtual]
30
- @type = type
31
- puts "Creating files for soaspec. options are #{options}"
32
- create_file(filename: 'Gemfile')
33
- create_file(filename: 'Rakefile')
34
- create_file(filename: '.rspec')
35
- create_file(filename: 'README.md')
36
- create_file(filename: '.travis.yml') if options[:ci] == 'travis'
37
- create_folder 'lib'
38
- create_files_for type
39
- create_file(filename: 'config/data/default.yml') # Example of data file
40
- create_file(filename: 'spec/spec_helper.rb')
41
- puts "Run 'bundle install' to install necessary gems"
42
- puts "Run 'rake spec' to run the tests"
43
- end
44
-
45
- long_desc <<-LONGDESC
46
- `soaspec add rest` will generate the initial files and folders for starting a testing project using soaspec
47
- \x5
48
-
49
- `soaspec add soap` will create example files testing against a virtual SOAP service
50
- \x5
51
-
52
- LONGDESC
53
- desc 'add [type] [name]', 'Add new ExchangeHandler'
54
- def add(type = 'rest', name = 'TestService')
55
- raise "Type '#{type}' is not available" unless %w[rest soap].include? type
56
-
57
- @name = name # Use instance variable for ERB
58
- create_file filename: File.join('lib', "#{name.snakecase}.rb"),
59
- content: retrieve_contents(File.join('lib', "new_#{type}_service.rb"))
60
- end
61
-
62
- desc 'cucumber', 'Add cucumber generic steps template within step_definitions folder'
63
- def cucumber
64
- create_file filename: File.join('features', 'step_definitions', 'generic_steps.rb'),
65
- content: retrieve_contents(File.join('../cucumber', 'generic_steps.rb'), false)
66
- end
67
-
68
- desc 'generate', 'Generate initial test code from wsdl'
69
- long_desc <<-LONGDESC
70
- If no wsdl is given a server will be started from which code to generate Exchanges
71
-
72
- `soaspec generate wsdl=wsdl name=ServiceName ` will generate the initial files and folders to test each operation in a wsdl
73
- \x5
74
- Additionally the auth parameter can be used to use basic authentication to retrieve the WSDL.
75
- To do use the following `soaspec generate --auth=basic`
76
- Note: This is still a work in progress and will only work for a very simple wsdl
77
- LONGDESC
78
- option :wsdl, default: nil, aliases: :w
79
- option :name, default: 'Service', aliases: :n
80
- option :ci, default: 'jenkins', banner: 'What Continuous Integration is used'
81
- option :auth
82
- option :open_browser, default: 'true'
83
- option :string_default, default: 'test string'
84
- def generate
85
- if options[:wsdl]
86
- generate_from_wsdl(options)
87
- else
88
- require 'launchy'
89
- require 'soaspec/generate_server'
90
- Soaspec::GenerateServer.run! do
91
- Launchy.open 'http://localhost:8999' if options[:open_browser] == 'true'
92
- end
93
- end
94
- end
95
-
96
- long_desc <<-LONGDESC
97
- Run virtual web services on localhost. See root for documentation of web services provided.
98
- LONGDESC
99
- desc 'virtual_server [port]', 'Run virtual web service on localhost'
100
- def virtual_server(port = '4999')
101
- ENV['port'] = port
102
- require 'soaspec/virtual_server'
103
- Soaspec::VirtualServer.run!(Port: port)
104
- end
105
-
106
- long_desc <<-LONGDESC
107
- Run pry with Soaspec and other relevant libraries loaded. Pass either the relative path to files desired with a
108
- '.rb' extension or the path to the folder to be loaded with 'require_all'
109
- LONGDESC
110
- desc 'pry [required_files]', 'Run pry with Soaspec and other relevant libraries loaded'
111
- def pry(required_files = nil)
112
- require 'soaspec'
113
-
114
- require 'require_all'
115
- require_all required_files if required_files
116
-
117
- require 'pry'
118
- Pry.start
119
- end
120
- end
121
- end
122
-
123
- Soaspec::Exe.start(ARGV)
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'thor'
4
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
5
+ require 'savon'
6
+ require 'soaspec'
7
+ require 'soaspec/virtual_server'
8
+ require 'soaspec/wsdl_generator'
9
+
10
+ module Soaspec
11
+ # Common executable for Soaspec
12
+ class Exe < Thor
13
+ include Soaspec::ExeHelpers
14
+ include Soaspec::WsdlGenerator
15
+
16
+ long_desc <<-LONGDESC
17
+ `soaspec new` will generate the initial files and folders for starting a testing project using soaspec
18
+ \x5
19
+
20
+ `soaspec new soap` will create example files testing against a SOAP service
21
+ \x5
22
+
23
+ `soaspec new rest` will create example files testing against a REST service
24
+ LONGDESC
25
+ desc 'new [type]', 'Initialize soaspec repository'
26
+ option :ci, default: 'jenkins', banner: 'What Continuous Integration is used'
27
+ option :virtual, type: :boolean, default: true, banner: 'Whether to set things up for a virtual server'
28
+ def new(type = 'initial')
29
+ @virtual = options[:virtual]
30
+ @type = type
31
+ puts "Creating files for soaspec. options are #{options}"
32
+ create_file(filename: 'Gemfile')
33
+ create_file(filename: 'Rakefile')
34
+ create_file(filename: '.rspec')
35
+ create_file(filename: 'README.md')
36
+ create_file(filename: '.travis.yml') if options[:ci] == 'travis'
37
+ create_folder 'lib'
38
+ create_files_for type
39
+ create_file(filename: 'config/data/default.yml') # Example of data file
40
+ create_file(filename: 'spec/spec_helper.rb')
41
+ puts "Run 'bundle install' to install necessary gems"
42
+ puts "Run 'rake spec' to run the tests"
43
+ end
44
+
45
+ long_desc <<-LONGDESC
46
+ `soaspec add rest` will generate the initial files and folders for starting a testing project using soaspec
47
+ \x5
48
+
49
+ `soaspec add soap` will create example files testing against a virtual SOAP service
50
+ \x5
51
+
52
+ LONGDESC
53
+ desc 'add [type] [name]', 'Add new ExchangeHandler'
54
+ def add(type = 'rest', name = 'TestService')
55
+ raise "Type '#{type}' is not available" unless %w[rest soap].include? type
56
+
57
+ @name = name # Use instance variable for ERB
58
+ create_file filename: File.join('lib', "#{name.snakecase}.rb"),
59
+ content: retrieve_contents(File.join('lib', "new_#{type}_service.rb"))
60
+ end
61
+
62
+ long_desc <<-LONGDESC
63
+ `soaspec cucumber` will add generic steps file within step definitions folder. It will also
64
+ add Gemfile, and other Cucumber setup files if not already added
65
+ \x5
66
+
67
+ LONGDESC
68
+ desc 'cucumber', 'Add cucumber generic steps template within step_definitions folder'
69
+ def cucumber
70
+ @cucumber = true
71
+ create_file(filename: 'Gemfile', ignore_if_present: true)
72
+ create_file(filename: 'features/support/env.rb', ignore_if_present: true)
73
+ create_file filename: File.join('features', 'step_definitions', 'generic_steps.rb'),
74
+ content: retrieve_contents(File.join('../cucumber', 'generic_steps.rb'), false)
75
+ end
76
+
77
+ desc 'generate', 'Generate initial test code from wsdl'
78
+ long_desc <<-LONGDESC
79
+ If no wsdl is given a server will be started from which code to generate Exchanges
80
+
81
+ `soaspec generate wsdl=wsdl name=ServiceName ` will generate the initial files and folders to test each operation in a wsdl
82
+ \x5
83
+ Additionally the auth parameter can be used to use basic authentication to retrieve the WSDL.
84
+ To do use the following `soaspec generate --auth=basic`
85
+ Note: This is still a work in progress and will only work for a very simple wsdl
86
+ LONGDESC
87
+ option :wsdl, default: nil, aliases: :w
88
+ option :name, default: 'Service', aliases: :n
89
+ option :ci, default: 'jenkins', banner: 'What Continuous Integration is used'
90
+ option :auth
91
+ option :open_browser, default: 'true'
92
+ option :string_default, default: 'test string'
93
+ option :port, default: nil, banner: 'What port to run generate server. Default is random'
94
+ def generate
95
+ if options[:wsdl]
96
+ generate_from_wsdl(options)
97
+ else
98
+ require 'launchy'
99
+ require 'soaspec/generate_server'
100
+ require 'random-port'
101
+ port = options[:port] || RandomPort::Pool.new.acquire.to_s
102
+ puts "Using random port '#{port}' for hosting generate server"
103
+
104
+ Soaspec::GenerateServer.run!(port: port) do
105
+ Launchy.open "http://localhost:#{port}" if options[:open_browser] == 'true'
106
+ end
107
+ end
108
+ end
109
+
110
+ long_desc <<-LONGDESC
111
+ Run virtual web services on localhost. See root for documentation of web services provided.
112
+ LONGDESC
113
+ desc 'virtual_server [port]', 'Run virtual web service on localhost'
114
+ def virtual_server(port = '4999')
115
+ ENV['port'] = port
116
+ require 'soaspec/virtual_server'
117
+ Soaspec::VirtualServer.run!(port: port)
118
+ end
119
+
120
+ long_desc <<-LONGDESC
121
+ Run pry with Soaspec and other relevant libraries loaded. Pass either the relative path to files desired with a
122
+ '.rb' extension or the path to the folder to be loaded with 'require_all'
123
+ LONGDESC
124
+ desc 'pry [required_files]', 'Run pry with Soaspec and other relevant libraries loaded'
125
+ def pry(required_files = nil)
126
+ require 'soaspec'
127
+
128
+ require 'require_all'
129
+ require_all required_files if required_files
130
+
131
+ require 'pry'
132
+ Pry.start
133
+ end
134
+ end
135
+ end
136
+
137
+ Soaspec::Exe.start(ARGV)
data/exe/xml_to_yaml_file CHANGED
@@ -1,42 +1,42 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'xmlsimple'
4
- require 'yaml'
5
- require 'fileutils'
6
-
7
- $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
8
-
9
- require 'soaspec'
10
-
11
- include Soaspec::ExeHelpers
12
-
13
- default_output_file = 'output.yml'
14
-
15
- # For all keys in a Hash, convert Camelcase to underscore separated
16
- def convert_hash_keys(value)
17
- case value
18
- when Array
19
- value.map { |v| convert_hash_keys(v) }
20
- when Hash
21
- Hash[value.map { |k, v| [k.snakecase, convert_hash_keys(v)] }]
22
- else
23
- value
24
- end
25
- end
26
-
27
- # Remove arrays created as another string
28
- def clean_up_yaml(yaml_string)
29
- yaml_string = yaml_string.gsub(/\R+(\s*)-/, '').gsub(/{}/, "''") # Remove arrays, {} -> ''
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") }
32
- end
33
-
34
- if ARGV[0]
35
- warn "Using '#{default_output_file}' as default output file since no 2nd argument passed" unless ARGV[1]
36
- hash = XmlSimple.xml_in(ARGV[0])
37
- converted = convert_hash_keys hash
38
- yaml_file = clean_up_yaml(converted.to_yaml)
39
- create_file(filename: ARGV[1] || default_output_file, content: yaml_file)
40
- else
41
- puts 'usage: xml_to_yaml_file [input.xml] [output.yml] '
42
- end
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'xmlsimple'
4
+ require 'yaml'
5
+ require 'fileutils'
6
+
7
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
8
+
9
+ require 'soaspec'
10
+
11
+ include Soaspec::ExeHelpers
12
+
13
+ default_output_file = 'output.yml'
14
+
15
+ # For all keys in a Hash, convert Camelcase to underscore separated
16
+ def convert_hash_keys(value)
17
+ case value
18
+ when Array
19
+ value.map { |v| convert_hash_keys(v) }
20
+ when Hash
21
+ Hash[value.map { |k, v| [k.snakecase, convert_hash_keys(v)] }]
22
+ else
23
+ value
24
+ end
25
+ end
26
+
27
+ # Remove arrays created as another string
28
+ def clean_up_yaml(yaml_string)
29
+ yaml_string = yaml_string.gsub(/\R+(\s*)-/, '').gsub(/{}/, "''") # Remove arrays, {} -> ''
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") }
32
+ end
33
+
34
+ if ARGV[0]
35
+ warn "Using '#{default_output_file}' as default output file since no 2nd argument passed" unless ARGV[1]
36
+ hash = XmlSimple.xml_in(ARGV[0])
37
+ converted = convert_hash_keys hash
38
+ yaml_file = clean_up_yaml(converted.to_yaml)
39
+ create_file(filename: ARGV[1] || default_output_file, content: yaml_file)
40
+ else
41
+ puts 'usage: xml_to_yaml_file [input.xml] [output.yml] '
42
+ end