rubycom 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +8 -8
  2. data/README.md +162 -146
  3. data/Rakefile +12 -12
  4. data/lib/rubycom.rb +156 -226
  5. data/lib/rubycom/arg_parse.rb +252 -0
  6. data/lib/rubycom/command_interface.rb +97 -0
  7. data/lib/rubycom/completions.rb +62 -0
  8. data/lib/rubycom/error_handler.rb +15 -0
  9. data/lib/rubycom/executor.rb +23 -0
  10. data/lib/rubycom/helpers.rb +98 -0
  11. data/lib/rubycom/output_handler.rb +15 -0
  12. data/lib/rubycom/parameter_extract.rb +262 -0
  13. data/lib/rubycom/singleton_commands.rb +78 -0
  14. data/lib/rubycom/sources.rb +99 -0
  15. data/lib/rubycom/version.rb +1 -1
  16. data/lib/rubycom/yard_doc.rb +146 -0
  17. data/rubycom.gemspec +14 -16
  18. data/test/rubycom/arg_parse_test.rb +247 -0
  19. data/test/rubycom/command_interface_test.rb +293 -0
  20. data/test/rubycom/completions_test.rb +94 -0
  21. data/test/rubycom/error_handler_test.rb +72 -0
  22. data/test/rubycom/executor_test.rb +64 -0
  23. data/test/rubycom/helpers_test.rb +467 -0
  24. data/test/rubycom/output_handler_test.rb +76 -0
  25. data/test/rubycom/parameter_extract_test.rb +141 -0
  26. data/test/rubycom/rubycom_test.rb +290 -548
  27. data/test/rubycom/singleton_commands_test.rb +122 -0
  28. data/test/rubycom/sources_test.rb +59 -0
  29. data/test/rubycom/util_test_bin.rb +8 -0
  30. data/test/rubycom/util_test_composite.rb +23 -20
  31. data/test/rubycom/util_test_module.rb +142 -112
  32. data/test/rubycom/util_test_no_singleton.rb +2 -2
  33. data/test/rubycom/util_test_sub_module.rb +13 -0
  34. data/test/rubycom/yard_doc_test.rb +165 -0
  35. metadata +61 -24
  36. data/lib/rubycom/arguments.rb +0 -133
  37. data/lib/rubycom/commands.rb +0 -63
  38. data/lib/rubycom/documentation.rb +0 -212
  39. data/test/rubycom/arguments_test.rb +0 -289
  40. data/test/rubycom/commands_test.rb +0 -51
  41. data/test/rubycom/documentation_test.rb +0 -186
  42. data/test/rubycom/util_test_job.yaml +0 -21
  43. data/test/rubycom/utility_tester.rb +0 -17
@@ -0,0 +1,99 @@
1
+ module Rubycom
2
+ module Sources
3
+ require 'method_source'
4
+
5
+ # Calls #source_commands and filters to the source string of the first command returned
6
+ #
7
+ # @param [Array] command the commands whose source should be returned
8
+ # @return [String] the source code string if the command was a Module or Method. Returns the command otherwise
9
+ def self.source_command(command)
10
+ self.source_commands([command]).first[:source]
11
+ end
12
+
13
+ # Checks commands then calls #map_sources
14
+ #
15
+ # @param [Array] commands the commands whose source should be returned
16
+ # @return [Hash] :command => the command from commands, :source => the source code string if the command was a Module or Method
17
+ def self.source_commands(commands)
18
+ com = self.check(commands)
19
+ self.map_sources(com)
20
+ end
21
+
22
+ # Provides upfront checking for this inputs to #source_commands
23
+ def self.check(commands)
24
+ raise ArgumentError, "#{commands} should be an Array but was #{commands.class}" unless commands.class == Array
25
+ commands.each { |cmd|
26
+ raise ArgumentError, "#{cmd} should be a Module, Method, Symbol, or String but was #{cmd.class}" unless [Module, Method, Symbol, String].include?(cmd.class)
27
+ }
28
+ end
29
+
30
+ # Maps each command in commands to a hash containing the command and the source string for that command.
31
+ # Uses #module_source and #method_source to look up source strings when command is a Module or Method.
32
+ #
33
+ # @param [Array] commands the commands whose source should be returned
34
+ # @return [Hash] :command => the command from commands, :source => the source code string if the command was a Module or Method
35
+ def self.map_sources(commands)
36
+ commands.map { |cmd|
37
+ {
38
+ command: cmd,
39
+ source: if cmd.class == Module
40
+ self.module_source(cmd)
41
+ elsif cmd.class == Method
42
+ self.method_source(cmd)
43
+ elsif cmd.class == Symbol || cmd.class == String
44
+ mod = cmd.to_s.split('::').reduce(Kernel){|last_mod, next_mod|
45
+ last_mod.const_get(next_mod.to_s.to_sym)
46
+ } rescue cmd
47
+ self.module_source(mod)
48
+ else
49
+ cmd
50
+ end
51
+ }
52
+ }
53
+ end
54
+
55
+ # Searches for the source location of the given module. Since modules can be defined in many locations, all source files
56
+ # containing a definition for the given module will be joined.
57
+ #
58
+ # @param [Module] mod the module to be sourced
59
+ # @return [String] a string representing the source of the given module or an empty string if no source file could be located
60
+ def self.module_source(mod)
61
+ return mod unless mod.class == Module
62
+ method_sources = mod.singleton_methods(true).select { |sym| ![:included, :extended].include?(sym) }.map { |sym|
63
+ mod.method(sym).source_location.first rescue nil
64
+ }
65
+ feature_sources = $LOADED_FEATURES.select{|file|
66
+ name_match = File.dirname(file) == File.dirname(File.realpath($0))
67
+ parent_match = File.dirname(File.dirname(file)) == File.dirname(File.dirname(File.realpath($0)))
68
+ ancestor_match = File.dirname(File.dirname(File.dirname(file))) == File.dirname(File.dirname(File.dirname(File.realpath($0))))
69
+ pwd_match = File.absolute_path(file).include?(Dir.pwd)
70
+ final = if name_match || parent_match || ancestor_match || pwd_match # prevents unnecessary file reading
71
+ (!File.read(file).match(/(class|module)\s+#{mod.name}/).nil?) rescue false
72
+ else
73
+ false
74
+ end
75
+ final
76
+ }
77
+ source_files = (method_sources + feature_sources).compact.uniq
78
+ unless source_files.include?($0) # prevents unnecessary file reading
79
+ source_files << $0 unless File.read($0).match(/(class|module)\s+#{mod.name}/).nil?
80
+ end
81
+
82
+ return '' if source_files.empty?
83
+ source_files.reduce(''){|source_str, next_file|
84
+ source_str << File.read(next_file)
85
+ source_str << "\n" unless source_str.end_with?("\n")
86
+ source_str
87
+ } || ''
88
+ end
89
+
90
+ # Discovers the source code for the given method.
91
+ #
92
+ # @param [Method] method the method to be source
93
+ # @return [String] the source of the specified method
94
+ def self.method_source(method)
95
+ return method unless method.class == Method
96
+ method.comment + method.source
97
+ end
98
+ end
99
+ end
@@ -1,3 +1,3 @@
1
1
  module Rubycom
2
- VERSION = "0.3.2"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -0,0 +1,146 @@
1
+ module Rubycom
2
+ module YardDoc
3
+ require 'yard'
4
+
5
+ # Transforms the command to a Hash representing the command and it's documentation
6
+ #
7
+ # @param [Array] command a Module or Method to be documented
8
+ # @param [Module] source_method a Module which will be used to retrieve module and method source code
9
+ # @return [Array] a Hash which is the result calling #map_doc
10
+ def self.document_command(command, source_method)
11
+ self.document_commands([command], source_method).first[:doc]
12
+ end
13
+
14
+ # Transforms each command in commands to a Hash representing the command and it's documentation
15
+ #
16
+ # @param [Array] commands a set of Modules and Methods to be documented
17
+ # @param [Module] source_method a Module which will be used to retrieve module and method source code
18
+ # @return [Array] a set of Hashes which are the result calling #map_doc
19
+ def self.document_commands(commands, source_method)
20
+ commands, source_method = self.check(commands, source_method)
21
+ self.map_doc(commands, source_method)
22
+ end
23
+
24
+ # Provides upfront checking for this inputs to #document_commands
25
+ def self.check(commands, source_fn)
26
+ YARD::Logger.instance.level = YARD::Logger::FATAL
27
+ raise ArgumentError, "#{source_fn} should be a Method or Proc but was #{source_fn.class}" unless [Method, Proc].include?(source_fn.class)
28
+ raise ArgumentError, "#{commands} should be an Array but was #{commands.class}" unless commands.class == Array
29
+ [commands, source_fn]
30
+ end
31
+
32
+ # Transforms each command in commands to a Hash representing the command and it's documentation
33
+ #
34
+ # @param [Array] commands a set of Modules and Methods to be documented
35
+ # @param [Method|Proc] source_method used to retrieve module and method source code
36
+ # @return [Array] a set of Hashes which are the result of calls to #module_doc and #method_doc
37
+ def self.map_doc(commands, source_method)
38
+ commands.map { |cmd|
39
+ {
40
+ command: cmd,
41
+ doc: if cmd.class == Module
42
+ self.module_doc(cmd, source_method)
43
+ elsif cmd.class == Method
44
+ self.method_doc(cmd, source_method)
45
+ else
46
+ {short_doc: '', full_doc: ''}
47
+ end
48
+ }
49
+ }
50
+ end
51
+
52
+ # Extracts elements of source code documentation for the given module. Calls #source_command on the given
53
+ # source_plugin to retrieve the method's source code.
54
+ #
55
+ # @param [Module] mod a Module instance representing the module whose documentation should be parsed
56
+ # @param [Method] source_method a Module which will be used to retrieve module and method source code
57
+ # @return [Hash] :short_doc => String, :full_doc => String, :sub_command_docs => [ { sub_command_name_symbol => String } ]
58
+ def self.module_doc(mod, source_method)
59
+ module_source = source_method.call(mod)
60
+ YARD::Registry.clear
61
+ YARD.parse_string(module_source.to_s)
62
+ doc_obj = YARD::Registry.at(mod.to_s)
63
+ return {short_doc: '', full_doc: ''} if doc_obj.nil?
64
+ {
65
+ short_doc: doc_obj.docstring.summary,
66
+ full_doc: doc_obj.docstring.to_s,
67
+ sub_command_docs: doc_obj.meths(:visibility => :public, :scope => :class).map { |doc_method|
68
+ {
69
+ doc_method.name => self.method_doc(mod.public_method(doc_method.name), doc_method)[:short_doc]
70
+ }
71
+ }.reduce({}, &:merge).merge(
72
+ doc_obj.mixins.select { |doc_mod| doc_mod.name != :Rubycom }.map { |doc_mod|
73
+ namespaced_mod_name = "#{doc_mod.namespace}::#{doc_mod.name}"
74
+ mod_source = source_method.call(namespaced_mod_name)
75
+ mod_source = source_method.call(doc_mod.name) if mod_source == namespaced_mod_name
76
+ YARD.parse_string(mod_source.to_s)
77
+ sub_doc_obj = YARD::Registry.at(doc_mod.to_s)
78
+ {
79
+ doc_mod.name => (sub_doc_obj.nil?) ? '' : sub_doc_obj.docstring.summary.to_s
80
+ }
81
+ }.reduce({}, &:merge)
82
+ )
83
+ }
84
+ end
85
+
86
+ # Extracts elements of source code documentation for the given method. Calls #source_command on the given source_plugin
87
+ # to retrieve the method's source code.
88
+ #
89
+ # @param [Method] method a Method instance representing the method whose documentation should be parsed
90
+ # @param [Method|Proc|YARD::CodeObjects::MethodObject] source_method called to retrieve the method's source code.
91
+ # Alternately this parameter can be a YARD::CodeObjects::MethodObject which will be used instead of looking
92
+ # up the method's source code
93
+ # @return [Hash] :short_doc => String, :full_doc => String,
94
+ # :tags => [ { :tag_name => String, :name => String, :types => [String], :text => String } ],
95
+ # :parameters => [ { :param_name => String, :type => :req|:opt|:rest, :default => Object, :doc_type => String, :doc => String } ]
96
+ def self.method_doc(method, source_method)
97
+ raise ArgumentError, "method should be a Method but was #{method.class}" unless method.class == Method
98
+ method_param_types = method.parameters.map { |type, sym| {sym => type} }.reduce({}, &:merge)
99
+ if source_method.class == YARD::CodeObjects::MethodObject
100
+ doc_obj = source_method
101
+ elsif source_method.is_a?(Proc) || source_method.is_a?(Method)
102
+ YARD::Registry.clear
103
+ YARD.parse_string(source_method.call(method))
104
+ method_name = method.name
105
+ doc_obj = YARD::Registry.at(method_name.to_s)
106
+ doc_obj = YARD::Registry.at("::#{method_name.to_s}") if doc_obj.nil?
107
+ doc_obj = YARD::Registry.at("\##{method_name.to_s}") if doc_obj.nil?
108
+ doc_obj = YARD::Registry.at(method_name.to_s.split('.').last) if doc_obj.nil?
109
+ raise ArgumentError, "No such method #{method_name} in the given source." if doc_obj.nil?
110
+ else
111
+ raise ArgumentError, "source_plugin should be YARD::CodeObjects::MethodObject|Method but was #{source_method.class}"
112
+ end
113
+ {
114
+ parameters: doc_obj.parameters.map { |k, v|
115
+ # YARD's parsing returns pairs of params and values
116
+ # if the param has a default value then the value is wrapped in a string
117
+ # required arguments have a value of nil
118
+ param_type = method_param_types[k.reverse.chomp('*').reverse.to_sym]
119
+ param_default = if param_type == :rest
120
+ []
121
+ else
122
+ (v.class == String) ? method.receiver.module_eval(v) : v
123
+ end
124
+ {
125
+ param_name: k,
126
+ type: param_type,
127
+ default: param_default,
128
+ doc_type: doc_obj.tags.select { |tag| tag.name == k.to_s }.map { |tag| tag.types }.join(','),
129
+ doc: doc_obj.tags.select { |tag| tag.name == k.to_s }.map { |tag| tag.text }.join("\n")
130
+ }
131
+ },
132
+ short_doc: doc_obj.base_docstring.summary.to_s,
133
+ full_doc: doc_obj.base_docstring.to_s,
134
+ tags: doc_obj.tags.map { |tag|
135
+ {
136
+ tag_name: tag.tag_name,
137
+ name: tag.name,
138
+ types: tag.types,
139
+ text: tag.text
140
+ }
141
+ }
142
+ }
143
+ end
144
+
145
+ end
146
+ end
@@ -1,26 +1,24 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'rubycom/version'
1
+ require "#{File.dirname(__FILE__)}/lib/rubycom/version.rb"
5
2
 
6
3
  Gem::Specification.new do |spec|
7
- spec.name = "rubycom"
4
+ spec.name = 'rubycom'
8
5
  spec.version = Rubycom::VERSION
9
- spec.authors = ["Danny Purcell"]
10
- spec.email = ["d.purcell.jr+rubycom@gmail.com"]
11
- spec.description = %q{Allows command-line access for all singleton methods in an including class. Reads Yard style documentation for command line help output. Uses Yaml for parsing options. Allows the user to make a command-line tool by simply including Rubycom at the bottom.}
12
- spec.summary = %q{Converts singleton methods to command-line functions upon inclusion.}
13
- spec.homepage = "http://dannypurcell.github.io/rubycom"
14
- spec.license = "MIT"
6
+ spec.authors = ['Danny Purcell']
7
+ spec.email = %w(d.purcell.jr+rubycom@gmail.com)
8
+ spec.description = %q{Enables command-line access for methods in an including module. Reads method documentation for command line help output. Parses command line options and flags. Turn your library into a command-line app by simply including Rubycom.}
9
+ spec.summary = %q{Turn your library into a command-line app by simply including Rubycom.}
10
+ spec.homepage = 'http://dannypurcell.github.io/rubycom'
11
+ spec.license = 'MIT'
15
12
 
16
13
  spec.files = `git ls-files`.split($/)
17
14
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
15
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
16
+ spec.require_paths = %w(lib)
20
17
 
21
- spec.add_development_dependency "bundler", "~> 1.3"
22
- spec.add_development_dependency "test-unit"
23
- spec.add_development_dependency "yard"
24
- spec.add_development_dependency "rake"
18
+ spec.add_development_dependency 'bundler'
19
+ spec.add_development_dependency 'test-unit'
20
+ spec.add_development_dependency 'yard'
21
+ spec.add_development_dependency 'rake'
25
22
  spec.add_dependency 'method_source'
23
+ spec.add_dependency 'parslet'
26
24
  end
@@ -0,0 +1,247 @@
1
+ require "#{File.dirname(__FILE__)}/../../lib/rubycom/arg_parse.rb"
2
+
3
+ require "#{File.dirname(__FILE__)}/util_test_module.rb"
4
+ require "#{File.dirname(__FILE__)}/util_test_composite.rb"
5
+ require "#{File.dirname(__FILE__)}/util_test_no_singleton.rb"
6
+
7
+ require 'test/unit'
8
+
9
+ class ArgParseTest < Test::Unit::TestCase
10
+
11
+ def test_parse_string
12
+ test_arg = "test_arg"
13
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
14
+ expected = {:args => ["test_arg"]}
15
+ assert_equal(expected, result)
16
+ end
17
+
18
+ def test_parse_empty
19
+ test_arg = []
20
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
21
+ expected = {}
22
+ assert_equal(expected, result)
23
+ end
24
+
25
+ def test_parse_bad_arg
26
+ test_arg = ["[1,2,\"3]"]
27
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
28
+ expected = {:args => ["[1,2,\"3]"]}
29
+ assert_equal(expected, result)
30
+ end
31
+
32
+ def test_parse_fixnum
33
+ test_arg = ["1234512415435"]
34
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
35
+ expected = {:args => [1234512415435]}
36
+ assert_equal(expected, result)
37
+ end
38
+
39
+ def test_parse_float
40
+ test_arg = ["12345.67890"]
41
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
42
+ expected = {:args => [12345.6789]}
43
+ assert_equal(expected, result)
44
+ end
45
+
46
+ def test_parse_timestamp
47
+ time = Time.new
48
+ test_arg = ["#{time.to_s}"]
49
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
50
+ expected = {:args => [YAML.load(time.to_s)]}
51
+ assert_equal(expected, result)
52
+ end
53
+
54
+ def test_parse_datetime
55
+ time = Time.new('2013-05-08 00:00:00 -0500')
56
+ date = Date.new(time.year, time.month, time.day)
57
+ test_arg = ["#{date.to_s}"]
58
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
59
+ expected = {:args => [YAML.load(date.to_s)]}
60
+ assert_equal(expected, result)
61
+ end
62
+
63
+ def test_parse_array
64
+ test_arg = "[\"1\", 2, \"a\", 'b']"
65
+ result = Rubycom::ArgParse.parse_command_line(test_arg.to_s)
66
+ expected = {:args => [["1", 2, "a", "b"]]}
67
+ assert_equal(expected, result)
68
+ end
69
+
70
+ def test_parse_hash
71
+ time = Time.new.to_s
72
+ test_arg = "{a: \"#{time}\"}"
73
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
74
+ expected = {args: [{'a' => time}]}
75
+ assert_equal(expected, result)
76
+ end
77
+
78
+ def test_parse_hash_group
79
+ test_arg = ":a: [1,2]\n:b: 1\n:c: test\n:d: 1.0\n:e: \"2013-05-08 23:21:52 -0500\"\n"
80
+ result = Rubycom::ArgParse.parse_command_line(test_arg.to_s)
81
+ expected = {:args => [{:a => [1, 2], :b => 1, :c => "test", :d => 1.0, :e => "2013-05-08 23:21:52 -0500"}]}
82
+ assert_equal(expected, result)
83
+ end
84
+
85
+ def test_parse_yaml
86
+ time_str = Time.now.to_s
87
+ test_arg = {:a => ["1", 2, "a", 'b'], :b => 1, :c => "test", :d => "#{time_str}"}
88
+ result = Rubycom::ArgParse.parse_command_line("#{test_arg.to_yaml}")
89
+ expected = {:args => [{:a => ["1", 2, "a", "b"], :b => 1, :c => "test", :d => "#{time_str}"}]}
90
+ assert_equal(expected, result)
91
+ end
92
+
93
+ def test_parse_code
94
+ test_arg = "def self.test_code_method; raise \"Fail - test_parse_code\";end"
95
+ result = Rubycom::ArgParse.parse_command_line(test_arg.to_s)
96
+ expected = {:args => ["def self.test_code_method; raise \"Fail - test_parse_code\";end"]}
97
+ assert_equal(expected, result)
98
+ end
99
+
100
+ def test_parse_array_opt
101
+ test_arg = ['--test_opt', "1,2,3"]
102
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
103
+ expected = {:opts=>{"test_opt"=>[1,2,3]}}
104
+ assert_equal(expected, result)
105
+ end
106
+
107
+ def test_parse_alternate_array_opt
108
+ test_arg = ['--test_opt', "[1,2,3]"]
109
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
110
+ expected = {:opts=>{"test_opt"=>[1,2,3]}}
111
+ assert_equal(expected, result)
112
+ end
113
+
114
+ def test_parse_unrecognized_array_opt
115
+ test_arg = ['--test_opt', "[1,2,\"3]"]
116
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
117
+ expected = {:opts=>{"test_opt"=>"[1,2,\"3]"}}
118
+ assert_equal(expected, result)
119
+ end
120
+
121
+ def test_parse_opt_string_eq
122
+ test_arg = ["-test_arg", "=", "test"]
123
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
124
+ expected = {:opts => {"test_arg" => "test"}}
125
+ assert_equal(expected, result)
126
+ end
127
+
128
+ def test_parse_opt_string_eq_quoted
129
+ test_arg = ["-test_arg", "=", "\"test\""]
130
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
131
+ expected = {:opts => {"test_arg" => "test"}}
132
+ assert_equal(expected, result)
133
+ end
134
+
135
+ def test_parse_opt_string_sp
136
+ test_arg = ["-test_arg", "test"]
137
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
138
+ expected = {:opts => {"test_arg" => "test"}}
139
+ assert_equal(expected, result)
140
+ end
141
+
142
+ def test_parse_opt_long_string_eq
143
+ test_arg = ['--test_arg', '=', 'test']
144
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
145
+ expected = {:opts => {"test_arg" => "test"}}
146
+ assert_equal(expected, result)
147
+ end
148
+
149
+ def test_parse_opt_long_string_sp
150
+ test_arg = ["--test_arg", "test"]
151
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
152
+ expected = {:opts => {"test_arg" => "test"}}
153
+ assert_equal(expected, result)
154
+ end
155
+
156
+ def test_parse_multi_mention
157
+ test_arg = ["--other", "=", 'testing', "--test_arg", "test", "--test_arg", "thing"]
158
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
159
+ expected = {:opts => {"other" => "testing", "test_arg" => ["test", "thing"]}}
160
+ assert_equal(expected, result)
161
+ end
162
+
163
+ def test_parse_multi_mention_mixed
164
+ test_arg = ["--test_arg", "--other", "=", 'testing', "--test_arg", "test", "--test_arg", "thing"]
165
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
166
+ expected = {:opts => {"other" => "testing", "test_arg" => [true, "test", "thing"]}}
167
+ assert_equal(expected, result)
168
+ end
169
+
170
+ def test_parse_flag_true_short
171
+ test_arg = "-t"
172
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
173
+ expected = {:opts => {"t" => true}}
174
+ assert_equal(expected, result)
175
+ end
176
+
177
+ def test_parse_flag_true_short_multi
178
+ test_arg = "-tuv"
179
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
180
+ expected = {:opts => {"t" => true, "u" => true, "v" => true}}
181
+ assert_equal(expected, result)
182
+ end
183
+
184
+ def test_parse_flag_true_short_multi_mention
185
+ test_arg = ["-tuv", "-no-tuv"]
186
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
187
+ expected = {:opts => {"t" => [true, false], "u" => [true, false], "v" => [true, false]}}
188
+ assert_equal(expected, result)
189
+ end
190
+
191
+ def test_parse_flag_true_long
192
+ test_arg = "--test_flag"
193
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
194
+ expected = {:opts => {"test_flag" => true}}
195
+ assert_equal(expected, result)
196
+ end
197
+
198
+ def test_parse_flag_false_short
199
+ test_arg = "-no-t"
200
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
201
+ expected = {:opts => {"t" => false}}
202
+ assert_equal(expected, result)
203
+ end
204
+
205
+ def test_parse_flag_false_short_multi
206
+ test_arg = "-no-abc"
207
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
208
+ expected = {:opts => {"a" => false, "b" => false, "c" => false}}
209
+ assert_equal(expected, result)
210
+ end
211
+
212
+ def test_parse_flag_false_long
213
+ test_arg = "--no-test_flag"
214
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
215
+ expected = {:opts => {"test_flag" => false}}
216
+ assert_equal(expected, result)
217
+ end
218
+
219
+ def test_parse_command_run
220
+ test_arg = ["UtilTestModule", "test_command_with_return", "testing_argument", "--test_option_int=10"]
221
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
222
+ expected = {:args => ["UtilTestModule", "test_command_with_return", "testing_argument"], :opts => {"test_option_int" => 10}}
223
+ assert_equal(expected, result)
224
+ end
225
+
226
+ def test_parse_command_run_mixed
227
+ test_arg = ["UtilTestModule", "test_command_mixed_options", "testing_arg", "[test1, test2]", "-test_opt='testing_option'", "{a: 'test_hsh_arg'}", "-test_bool=true", "some", "other", "args"]
228
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
229
+ expected = {:args => ["UtilTestModule", "test_command_mixed_options", "testing_arg", ["test1", "test2"], {"a" => "test_hsh_arg"}, "some", "other", "args"], :opts => {"test_bool" => true, "test_opt" => "testing_option"}}
230
+ assert_equal(expected, result)
231
+ end
232
+
233
+ def test_parse_command_run_mixed_args_opts
234
+ test_arg = ["-test_opt", "testing_option", "UtilTestModule", "-test_bool", "true", "test_command_mixed_options", "testing_arg", "[test1, test2]", "{a: 'test_hsh_arg'}", "some", "other", "args"]
235
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
236
+ expected = {:args => ["UtilTestModule", "test_command_mixed_options", "testing_arg", ["test1", "test2"], {"a" => "test_hsh_arg"}, "some", "other", "args"], :opts => {"test_bool" => true, "test_opt" => "testing_option"}}
237
+ assert_equal(expected, result)
238
+ end
239
+
240
+ def test_parse_command_run_mixed_opts_flag
241
+ test_arg = ["--test_bool", "-test_opt", "testing_option", "UtilTestModule", "test_command_mixed_options", "testing_arg", "[test1, test2]", "{a: 'test_hsh_arg'}", "some", "other", "args"]
242
+ result = Rubycom::ArgParse.parse_command_line(test_arg)
243
+ expected = {:args => ["UtilTestModule", "test_command_mixed_options", "testing_arg", ["test1", "test2"], {"a" => "test_hsh_arg"}, "some", "other", "args"], :opts => {"test_bool" => true, "test_opt" => "testing_option"}}
244
+ assert_equal(expected, result)
245
+ end
246
+
247
+ end