ehbrs-tools 0.16.4 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ehbrs/cooking_book.rb +9 -0
  3. data/lib/ehbrs/cooking_book/build.rb +45 -0
  4. data/lib/ehbrs/cooking_book/build/base_page.rb +43 -0
  5. data/lib/ehbrs/cooking_book/build/index_page.rb +26 -0
  6. data/lib/ehbrs/cooking_book/build/recipe_page.rb +27 -0
  7. data/lib/ehbrs/cooking_book/project.rb +31 -0
  8. data/lib/ehbrs/cooking_book/recipe.rb +37 -0
  9. data/lib/ehbrs/cooking_book/recipe/ingredient.rb +21 -0
  10. data/lib/ehbrs/cooking_book/recipe/measure.rb +60 -0
  11. data/lib/ehbrs/cooking_book/recipe/part.rb +32 -0
  12. data/lib/ehbrs/music.rb +9 -0
  13. data/lib/ehbrs/music/album.rb +42 -0
  14. data/lib/ehbrs/observers/base.rb +1 -1
  15. data/lib/ehbrs/observers/with_persistence.rb +1 -1
  16. data/lib/ehbrs/patches/module/erb_template.rb +11 -0
  17. data/lib/ehbrs/patches/object/erb_template.rb +9 -0
  18. data/lib/ehbrs/patches/object/template.rb +7 -0
  19. data/lib/ehbrs/runner.rb +6 -13
  20. data/lib/ehbrs/runner/cooking_book.rb +30 -0
  21. data/lib/ehbrs/runner/cooking_book/build.rb +32 -0
  22. data/lib/ehbrs/runner/music.rb +16 -0
  23. data/lib/ehbrs/runner/music/selected.rb +63 -0
  24. data/lib/ehbrs/runner/telegram.rb +26 -0
  25. data/lib/ehbrs/runner/telegram/send_message.rb +29 -0
  26. data/lib/ehbrs/runner/videos/unsupported.rb +1 -1
  27. data/lib/ehbrs/runner/web_utils/videos/upload.rb +1 -1
  28. data/lib/ehbrs/telegram.rb +9 -0
  29. data/lib/ehbrs/telegram/message_sending.rb +32 -0
  30. data/lib/ehbrs/tools/application.rb +13 -0
  31. data/lib/ehbrs/tools/instance.rb +16 -0
  32. data/lib/ehbrs/tools/version.rb +1 -1
  33. data/lib/ehbrs/videos/track.rb +1 -19
  34. data/lib/ehbrs/videos/unsupported/check_support.rb +1 -1
  35. data/lib/ehbrs/videos/unsupported/checks/codec_extra_unlisted.rb +1 -1
  36. data/lib/ehbrs/videos/unsupported/checks/codec_extra_unsupported.rb +1 -1
  37. data/lib/ehbrs/videos/unsupported/checks/codec_unlisted.rb +2 -2
  38. data/lib/ehbrs/videos/unsupported/checks/codec_unsupported.rb +1 -1
  39. data/lib/ehbrs/videos/unsupported/fix_profile.rb +0 -13
  40. data/lib/ehbrs/videos/unsupported/fixes/supported_codec.rb +10 -10
  41. data/lib/ehbrs/videos/unsupported/profiles/aoc.rb +27 -0
  42. data/template/ehbrs/cooking_book/build/base_page/layout.html.erb +20 -0
  43. data/template/ehbrs/cooking_book/build/index_page/inner.html.erb +6 -0
  44. data/template/ehbrs/cooking_book/build/recipe_page/inner.html.erb +6 -0
  45. data/template/ehbrs/cooking_book/build/recipe_page/part.html.erb +27 -0
  46. data/vendor/eac_cli/lib/eac_cli/core_ext.rb +2 -0
  47. data/vendor/eac_cli/lib/eac_cli/definition/alternative.rb +4 -7
  48. data/vendor/eac_cli/lib/eac_cli/definition/argument_option.rb +8 -0
  49. data/vendor/eac_cli/lib/eac_cli/definition/base_option.rb +21 -9
  50. data/vendor/eac_cli/lib/eac_cli/definition/base_option/initialize_args_parser.rb +47 -0
  51. data/vendor/eac_cli/lib/eac_cli/definition/boolean_option.rb +8 -0
  52. data/vendor/eac_cli/lib/eac_cli/definition/positional_argument.rb +12 -0
  53. data/vendor/eac_cli/lib/eac_cli/docopt/doc_builder.rb +15 -1
  54. data/vendor/eac_cli/lib/eac_cli/docopt/runner_context_replacement.rb +15 -0
  55. data/vendor/eac_cli/lib/eac_cli/docopt/runner_extension.rb +5 -0
  56. data/vendor/eac_cli/lib/eac_cli/parser/alternative.rb +4 -4
  57. data/vendor/eac_cli/lib/eac_cli/parser/alternative/long_options.rb +37 -0
  58. data/vendor/eac_cli/lib/eac_cli/parser/alternative/option_argument.rb +29 -0
  59. data/vendor/eac_cli/lib/eac_cli/parser/alternative/options.rb +7 -36
  60. data/vendor/eac_cli/lib/eac_cli/parser/alternative/short_options.rb +45 -0
  61. data/vendor/eac_cli/lib/eac_cli/parser/collector.rb +3 -17
  62. data/vendor/eac_cli/lib/eac_cli/patches/object/runner_with.rb +2 -1
  63. data/vendor/eac_cli/lib/eac_cli/runner.rb +0 -48
  64. data/vendor/eac_cli/lib/eac_cli/runner/after_class_methods.rb +29 -0
  65. data/vendor/eac_cli/lib/eac_cli/runner/instance_methods.rb +31 -0
  66. data/vendor/eac_cli/lib/eac_cli/runner_with/subcommands.rb +15 -3
  67. data/vendor/eac_cli/lib/eac_cli/runner_with_set.rb +50 -0
  68. data/vendor/eac_cli/lib/eac_cli/version.rb +1 -1
  69. data/vendor/eac_cli/spec/lib/eac_cli/definition/alternative_spec.rb +4 -0
  70. data/vendor/eac_cli/spec/lib/eac_cli/runner_spec.rb +43 -4
  71. data/vendor/eac_ruby_base0/Gemfile +5 -0
  72. data/vendor/eac_ruby_base0/eac_ruby_base0.gemspec +20 -0
  73. data/vendor/eac_ruby_base0/lib/eac_ruby_base0.rb +7 -0
  74. data/vendor/eac_ruby_base0/lib/eac_ruby_base0/application.rb +69 -0
  75. data/vendor/eac_ruby_base0/lib/eac_ruby_base0/jobs_runner.rb +31 -0
  76. data/vendor/eac_ruby_base0/lib/eac_ruby_base0/patches.rb +4 -0
  77. data/vendor/eac_ruby_base0/lib/eac_ruby_base0/patches/class.rb +4 -0
  78. data/vendor/eac_ruby_base0/lib/eac_ruby_base0/patches/class/jobs_runner.rb +10 -0
  79. data/vendor/eac_ruby_base0/lib/eac_ruby_base0/patches/object.rb +5 -0
  80. data/vendor/eac_ruby_base0/lib/eac_ruby_base0/patches/object/runner_with.rb +5 -0
  81. data/vendor/eac_ruby_base0/lib/eac_ruby_base0/runner.rb +54 -0
  82. data/vendor/eac_ruby_base0/lib/eac_ruby_base0/runner/test_all.rb +22 -0
  83. data/vendor/eac_ruby_base0/lib/eac_ruby_base0/runner_with.rb +9 -0
  84. data/vendor/eac_ruby_base0/lib/eac_ruby_base0/runner_with/confirmable.rb +21 -0
  85. data/vendor/eac_ruby_base0/lib/eac_ruby_base0/runner_with/filesystem_traverser.rb +52 -0
  86. data/vendor/eac_ruby_base0/lib/eac_ruby_base0/version.rb +5 -0
  87. data/vendor/eac_ruby_base0/spec/rubocop_spec.rb +7 -0
  88. data/vendor/eac_ruby_base0/spec/spec_helper.rb +100 -0
  89. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/common_concern/module_setup.rb +16 -6
  90. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/common_constructor.rb +2 -99
  91. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/common_constructor/class_initialize.rb +29 -0
  92. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/common_constructor/instance_initialize.rb +53 -0
  93. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/common_constructor/super_args.rb +54 -0
  94. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/docopt_runner/_subcommands.rb +10 -1
  95. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/fs/traverser.rb +0 -2
  96. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/inflector.rb +4 -1
  97. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/local_time_zone.rb +48 -0
  98. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/class/settings_provider.rb +10 -0
  99. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/kernel.rb +4 -0
  100. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/kernel/nyi.rb +8 -0
  101. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/module/template.rb +10 -0
  102. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/object/if_nil.rb +17 -0
  103. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/object/template.rb +1 -8
  104. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/pathname/basename_sub.rb +2 -2
  105. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/time/required_zone.rb +11 -0
  106. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/version.rb +1 -1
  107. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/yaml.rb +8 -0
  108. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/common_concern_spec.rb +14 -4
  109. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/common_constructor_spec.rb +30 -0
  110. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/inflector_spec.rb +2 -1
  111. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/local_time_zone_spec.rb +17 -0
  112. data/vendor/ehbrs_ruby_utils/lib/ehbrs_ruby_utils/version.rb +1 -1
  113. data/vendor/ehbrs_ruby_utils/lib/ehbrs_ruby_utils/videos/stream.rb +1 -1
  114. metadata +87 -8
  115. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/time/default_time_zone_set.rb +0 -5
  116. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/time/local_time_zone.rb +0 -25
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ class Parser
5
+ class Alternative
6
+ module OptionArgument
7
+ private
8
+
9
+ attr_accessor :argument_option
10
+
11
+ def argument_option_collect_argv(option)
12
+ self.argument_option = option
13
+ self.phase = PHASE_OPTION_ARGUMENT
14
+ end
15
+
16
+ def option_argument_collect(option, value)
17
+ collector.collect(option, value)
18
+ self.argument_option = nil
19
+ self.phase = PHASE_ANY
20
+ option
21
+ end
22
+
23
+ def option_argument_collect_argv_value
24
+ option_argument_collect(argument_option, argv_enum.peek)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -4,49 +4,20 @@ module EacCli
4
4
  class Parser
5
5
  class Alternative
6
6
  module Options
7
- DOUBLE_DASH = '--'
8
-
9
7
  private
10
8
 
11
- attr_accessor :argument_option, :double_dash
12
-
13
- def argument_option_collect_argv(option)
14
- self.argument_option = option
15
- self.phase = PHASE_OPTION_ARGUMENT
16
- end
17
-
18
- def argv_current_option?
19
- phase == PHASE_ANY && argv_enum.peek.start_with?('-')
20
- end
21
-
22
- def argv_current_double_dash?
23
- argv_enum.peek == DOUBLE_DASH && !double_dash
24
- end
25
-
26
9
  def boolean_option_collect_argv(option)
27
10
  collector.collect(option, true)
28
11
  end
29
12
 
30
- def option_argument_collect_argv_value
31
- collector.collect(argument_option, argv_enum.peek)
32
- self.argument_option = nil
33
- self.phase = PHASE_ANY
34
- end
35
-
36
- def option_collect_argv_value
37
- return double_dash_collect_argv_value if argv_current_double_dash?
38
-
39
- alternative.options.any? do |option|
40
- next false unless [option.short, option.long].include?(argv_enum.peek)
41
-
42
- if option.argument?
43
- argument_option_collect_argv(option)
44
- else
45
- boolean_option_collect_argv(option)
46
- end
13
+ def option_collect_option(option)
14
+ if option.argument?
15
+ argument_option_collect_argv(option)
16
+ else
17
+ boolean_option_collect_argv(option)
18
+ end
47
19
 
48
- true
49
- end || raise_argv_current_invalid_option
20
+ option
50
21
  end
51
22
 
52
23
  def raise_argv_current_invalid_option
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ class Parser
5
+ class Alternative
6
+ module ShortOptions
7
+ SHORT_OPTION_PREFIX = '-'
8
+
9
+ private
10
+
11
+ def argv_current_short_option?
12
+ phase == PHASE_ANY && argv_enum.peek.start_with?(SHORT_OPTION_PREFIX) &&
13
+ !argv_current_long_option?
14
+ end
15
+
16
+ def find_short_option(char)
17
+ alternative.options.find { |option| short_without_prefix(option.short) == char }
18
+ end
19
+
20
+ def short_option_collect_argv_value
21
+ last_option = nil
22
+ short_without_prefix(argv_enum.peek).each_char do |char|
23
+ raise_error "Option \"#{last_option}\" requires a argument not provided" if
24
+ last_option.present?
25
+
26
+ collected_option = short_option_collect_char(char)
27
+ last_option = collected_option if collected_option.argument?
28
+ end
29
+ end
30
+
31
+ # @return [EacCli::Definition::BaseOption] The option collected.
32
+ def short_option_collect_char(char)
33
+ option = find_short_option(char)
34
+ raise_error "Invalid short option \"#{char}\"" unless option
35
+
36
+ option_collect_option(option)
37
+ end
38
+
39
+ def short_without_prefix(short)
40
+ short.gsub(/\A#{::Regexp.quote(SHORT_OPTION_PREFIX)}/, '')
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -24,11 +24,7 @@ module EacCli
24
24
  end
25
25
 
26
26
  def collect(option, value)
27
- if data[option].is_a?(::Array)
28
- data[option] << value
29
- else
30
- data[option] = value
31
- end
27
+ data[option] = option.build_value(value, data[option])
32
28
  end
33
29
 
34
30
  def supplied?(option)
@@ -42,18 +38,8 @@ module EacCli
42
38
  end
43
39
 
44
40
  def default_values
45
- definition.options.each { |option| data[option] = option_default_value(option) }
46
- definition.positional.each do |positional|
47
- data[positional] = positional_default_value(positional)
48
- end
49
- end
50
-
51
- def option_default_value(option)
52
- option.argument? ? nil : false
53
- end
54
-
55
- def positional_default_value(positional)
56
- positional.repeat? ? [] : nil
41
+ definition.options.each { |option| data[option] = option.default_value }
42
+ definition.positional.each { |positional| data[positional] = positional.default_value }
57
43
  end
58
44
  end
59
45
  end
@@ -3,6 +3,7 @@
3
3
  require 'eac_ruby_utils/core_ext'
4
4
  require 'eac_cli/runner'
5
5
  require 'eac_cli/runner_with'
6
+ require 'eac_cli/runner_with_set'
6
7
 
7
8
  class Object
8
9
  def runner_with(*runners, &block)
@@ -10,7 +11,7 @@ class Object
10
11
  enable_simple_cache
11
12
  enable_console_speaker
12
13
  runners.each do |runner|
13
- include runner_with_to_module(runner)
14
+ include ::EacCli::RunnerWithSet.default.item_to_module(runner)
14
15
  end
15
16
  runner_definition(&block) if block
16
17
  end
@@ -47,53 +47,5 @@ module EacCli
47
47
  include ActiveSupport::Callbacks
48
48
  define_callbacks :run
49
49
  end
50
-
51
- module AfterClassMethods
52
- def create(*runner_context_args)
53
- r = new
54
- r.runner_context = ::EacCli::Runner::Context.new(r, *runner_context_args)
55
- r
56
- end
57
-
58
- def run(*runner_context_args)
59
- r = create(*runner_context_args)
60
- r.run_run
61
- r
62
- end
63
-
64
- def runner_definition(&block)
65
- @runner_definition ||= super_runner_definition
66
- @runner_definition.instance_eval(&block) if block
67
- @runner_definition
68
- end
69
-
70
- def super_runner_definition
71
- superclass.try(:runner_definition).if_present(&:dup) || ::EacCli::Definition.new
72
- end
73
- end
74
-
75
- module InstanceMethods
76
- def run_run
77
- parsed
78
- run_callbacks(:run) { run }
79
- rescue ::EacCli::Runner::Exit # rubocop:disable Lint/SuppressedException
80
- # Do nothing
81
- end
82
-
83
- def runner_context
84
- return @runner_context if @runner_context
85
-
86
- raise 'Context was required, but was not set yet'
87
- end
88
-
89
- def runner_context=(new_runner_context)
90
- @runner_context = new_runner_context
91
- @parsed = nil
92
- end
93
-
94
- def parsed
95
- @parsed ||= ::EacCli::Parser.new(self.class.runner_definition, runner_context.argv).parsed
96
- end
97
- end
98
50
  end
99
51
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Runner
5
+ module AfterClassMethods
6
+ def create(*runner_context_args)
7
+ r = new
8
+ r.runner_context = ::EacCli::Runner::Context.new(r, *runner_context_args)
9
+ r
10
+ end
11
+
12
+ def run(*runner_context_args)
13
+ r = create(*runner_context_args)
14
+ r.run_run
15
+ r
16
+ end
17
+
18
+ def runner_definition(&block)
19
+ @runner_definition ||= super_runner_definition
20
+ @runner_definition.instance_eval(&block) if block
21
+ @runner_definition
22
+ end
23
+
24
+ def super_runner_definition
25
+ superclass.try(:runner_definition).if_present(&:dup) || ::EacCli::Definition.new
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Runner
5
+ module InstanceMethods
6
+ def run_run
7
+ parsed
8
+ run_callbacks(:run) { run }
9
+ rescue ::EacCli::Parser::Error => e
10
+ $stderr.write("#{e}\n")
11
+ rescue ::EacCli::Runner::Exit # rubocop:disable Lint/SuppressedException
12
+ # Do nothing
13
+ end
14
+
15
+ def runner_context
16
+ return @runner_context if @runner_context
17
+
18
+ raise 'Context was required, but was not set yet'
19
+ end
20
+
21
+ def runner_context=(new_runner_context)
22
+ @runner_context = new_runner_context
23
+ @parsed = nil
24
+ end
25
+
26
+ def parsed
27
+ @parsed ||= ::EacCli::Parser.new(self.class.runner_definition, runner_context.argv).parsed
28
+ end
29
+ end
30
+ end
31
+ end
@@ -6,6 +6,14 @@ require 'eac_ruby_utils/core_ext'
6
6
  module EacCli
7
7
  module RunnerWith
8
8
  module Subcommands
9
+ class << self
10
+ def runner?(object)
11
+ ::EacCli::Runner.runner?(object) || (
12
+ object.is_a?(::Class) && object < ::EacRubyUtils::Console::DocoptRunner
13
+ )
14
+ end
15
+ end
16
+
9
17
  common_concern do
10
18
  include ::EacCli::Runner
11
19
  end
@@ -19,7 +27,7 @@ module EacCli
19
27
  def available_subcommands_auto
20
28
  self.class.constants
21
29
  .map { |name| [name.to_s.underscore.gsub('_', '-'), self.class.const_get(name)] }
22
- .select { |c| ::EacCli::Runner.runner?(c[1]) }
30
+ .select { |c| ::EacCli::RunnerWith::Subcommands.runner?(c[1]) }
23
31
  .to_h.with_indifferent_access
24
32
  end
25
33
 
@@ -32,7 +40,7 @@ module EacCli
32
40
  end
33
41
 
34
42
  def help_extra_text
35
- (['Subcommands:'] + available_subcommands.keys.map { |s| " #{s}" })
43
+ (['Subcommands:'] + available_subcommands.keys.sort.map { |s| " #{s}" })
36
44
  .map { |v| "#{v}\n" }.join
37
45
  end
38
46
 
@@ -49,7 +57,11 @@ module EacCli
49
57
 
50
58
  def run_with_subcommand
51
59
  if subcommand_name
52
- subcommand_runner.run_run
60
+ if subcommand_runner.respond_to?(:run_run)
61
+ subcommand_runner.run_run
62
+ else
63
+ subcommand_runner.run
64
+ end
53
65
  else
54
66
  run_without_subcommand
55
67
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ class RunnerWithSet
5
+ class << self
6
+ def default
7
+ @default ||= new
8
+ end
9
+ end
10
+
11
+ def add_namespace(namespace)
12
+ namespace = sanitize_namespace(namespace)
13
+ raise "\"#{namespace}\" already was included" if namespace_set.include?(namespace)
14
+
15
+ namespace_set << namespace
16
+ self
17
+ end
18
+
19
+ def item_to_module(item)
20
+ item.is_a?(::Module) ? item : key_to_module(item)
21
+ end
22
+
23
+ def namespaces
24
+ namespace_set.dup
25
+ end
26
+
27
+ private
28
+
29
+ def namespace_set
30
+ @namespace_set ||= ::Array.new
31
+ end
32
+
33
+ def key_to_module(key)
34
+ namespace_set.lazy
35
+ .map { |namespace| key_to_module_in_namespace(namespace, key) }
36
+ .find(&:present?) ||
37
+ raise("Not module found with key \"#{key}\" (Namespaces: #{namespace_set})")
38
+ end
39
+
40
+ def key_to_module_in_namespace(namespace, key)
41
+ namespace.const_get(key.to_s.camelize)
42
+ rescue ::NameError
43
+ nil
44
+ end
45
+
46
+ def sanitize_namespace(source)
47
+ source.is_a?(::Module) ? source : source.to_s.constantize
48
+ end
49
+ end
50
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EacCli
4
- VERSION = '0.12.4'
4
+ VERSION = '0.15.0'
5
5
  end
@@ -7,6 +7,10 @@ RSpec.describe ::EacCli::Definition::Alternative do
7
7
 
8
8
  it { expect { instance.arg_opt '-a', '--opt2', 'A argument option' }.not_to raise_error }
9
9
  it { expect { instance.bool_opt '-b', '--opt1', 'A boolean option' }.not_to raise_error }
10
+ it { expect { instance.bool_opt '-b', '--no-description' }.not_to raise_error }
11
+ it { expect { instance.bool_opt '--opt1', 'A option without short' }.not_to raise_error }
12
+ it { expect { instance.bool_opt '-b', 'A option without long' }.not_to raise_error }
13
+ it { expect { instance.bool_opt 'A option without selectors' }.to raise_error(::StandardError) }
10
14
  it { expect { instance.options_argument(true) }.not_to raise_error }
11
15
  it { expect { instance.pos_arg :pos1 }.not_to raise_error }
12
16
  it { expect { instance.pos_arg :pos2, optional: true, repeat: true }.not_to raise_error }
@@ -11,7 +11,9 @@ RSpec.describe ::EacCli::Runner do
11
11
 
12
12
  runner_definition do
13
13
  arg_opt '-o', '--opt1', 'A arg option.'
14
- bool_opt '-o', '--opt2', 'A boolean option'
14
+ bool_opt '-p', '--opt2', 'A boolean option'
15
+ arg_opt '-q', '--opt4', 'A repeatable argument option.', repeat: true
16
+ bool_opt '-r', '--opt5', 'A repeatable boolean option', repeat: true
15
17
  pos_arg :pos1
16
18
  pos_arg :pos2, repeat: true, optional: true
17
19
  alt do
@@ -29,7 +31,7 @@ RSpec.describe ::EacCli::Runner do
29
31
  context 'when all args are supplied' do
30
32
  let(:argv) { %w[--opt1 aaa --opt2 bbb ccc ddd] }
31
33
  let(:parsed_expected) do
32
- { opt1: 'aaa', opt2: true, opt3: false, pos1: 'bbb',
34
+ { opt1: 'aaa', opt2: true, opt3: false, opt4: [], opt5: 0, pos1: 'bbb',
33
35
  pos2: %w[ccc ddd] }
34
36
  end
35
37
 
@@ -40,9 +42,33 @@ RSpec.describe ::EacCli::Runner do
40
42
  it { expect(instance.parsed.pos2).to eq(%w[ccc ddd]) }
41
43
  end
42
44
 
45
+ context 'with long option and argument in same position' do
46
+ let(:argv) { %w[--opt1=aaa pos1] }
47
+
48
+ it { expect(instance.parsed.opt1).to eq('aaa') }
49
+ end
50
+
51
+ context 'with valid grouped short options' do
52
+ let(:argv) { %w[-po aaa pos1] }
53
+
54
+ it { expect(instance.parsed.opt1).to eq('aaa') }
55
+ it { expect(instance.parsed.opt2?).to eq(true) }
56
+ end
57
+
58
+ context 'with invalid grouped short options' do
59
+ let(:argv) { %w[-op aaa pos1] }
60
+
61
+ it do
62
+ expect { instance.parsed }.to raise_error(::EacCli::Parser::Error)
63
+ end
64
+ end
65
+
43
66
  context 'when only required args are supplied' do
44
67
  let(:argv) { %w[bbb] }
45
- let(:parsed_expected) { { opt1: nil, opt2: false, opt3: false, pos1: 'bbb', pos2: [] } }
68
+ let(:parsed_expected) do
69
+ { opt1: nil, opt2: false, opt3: false, opt4: [], opt5: 0, pos1: 'bbb',
70
+ pos2: [] }
71
+ end
46
72
 
47
73
  it { expect(parsed_actual).to eq(parsed_expected) }
48
74
  it { expect(instance.parsed.opt1).to be_nil }
@@ -61,12 +87,25 @@ RSpec.describe ::EacCli::Runner do
61
87
 
62
88
  context 'when alternative args are supplied' do
63
89
  let(:argv) { %w[--opt3] }
64
- let(:parsed_expected) { { opt1: nil, opt2: false, opt3: true, pos1: nil, pos2: [] } }
90
+ let(:parsed_expected) do
91
+ { opt1: nil, opt2: false, opt3: true, opt4: [], opt5: 0, pos1: nil,
92
+ pos2: [] }
93
+ end
65
94
 
66
95
  it { expect(parsed_actual).to eq(parsed_expected) }
67
96
  it { expect(instance.parsed.opt3?).to eq(true) }
68
97
  end
69
98
 
99
+ context 'when repeated options are supplied' do
100
+ let(:argv) { %w[--opt5 -rrr --opt4=A -q B --opt4 C AAA] }
101
+ let(:parsed_expected) do
102
+ { opt1: nil, opt2: false, opt3: false, opt4: %w[A B C], opt5: 4, pos1: 'AAA',
103
+ pos2: [] }
104
+ end
105
+
106
+ it { expect(parsed_actual).to eq(parsed_expected) }
107
+ end
108
+
70
109
  context 'when extra args are not supplied' do
71
110
  let(:runner_class) do
72
111
  the_module = described_class