rubycom 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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