File: command_spec.rb

package info (click to toggle)
ruby-commander 4.6.0-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 360 kB
  • sloc: ruby: 1,971; makefile: 9
file content (198 lines) | stat: -rw-r--r-- 6,460 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# frozen_string_literal: true

require 'spec_helper'

describe Commander::Command do
  include Commander::Methods

  before :each do
    mock_terminal
    create_test_command
  end

  describe 'Options' do
    before :each do
      @options = Commander::Command::Options.new
    end

    it 'should act like an open struct' do
      @options.send = 'mail'
      @options.call = true
      expect(@options.send).to eq('mail')
      expect(@options.call).to eq(true)
    end

    it 'should allow __send__ to function as always' do
      @options.send = 'foo'
      expect(@options.__send__(:send)).to eq('foo')
    end
  end

  describe '#option' do
    it 'should add options' do
      expect { @command.option '--recursive' }.to change(@command.options, :length).from(1).to(2)
    end

    it 'should allow procs as option handlers' do
      @command.option('--recursive') { |recursive| expect(recursive).to be true }
      @command.run '--recursive'
    end

    it 'should allow usage of common method names' do
      @command.option '--open file'
      @command.when_called { |_, options| expect(options.open).to eq('foo') }
      @command.run '--open', 'foo'
    end
  end

  describe '#run' do
    describe 'should invoke #when_called' do
      it 'with arguments seperated from options' do
        @command.when_called { |args, _options| expect(args.join(' ')).to eq('just some args') }
        @command.run '--verbose', 'just', 'some', 'args'
      end

      it 'calling the #call method by default when an object is called' do
        object = double 'Object'
        expect(object).to receive(:call).once
        @command.when_called object
        @command.run 'foo'
      end

      it 'should allow #action as an alias to #when_called' do
        object = double 'Object'
        expect(object).to receive(:call).once
        @command.action object
        @command.run 'foo'
      end

      it 'calling an arbitrary method when an object is called' do
        object = double 'Object'
        expect(object).to receive(:foo).once
        @command.when_called object, :foo
        @command.run 'foo'
      end

      it 'should raise an error when no handler is present' do
        expect { @command.when_called }.to raise_error(ArgumentError)
      end

      it 'should be able to be run more than once' do
        expect(@command.run('once')).to eql('test once')
        expect(@command.run('twice')).to eql('test twice')
      end

      it 'should not accumulate entries in @proxy_options when run twice' do
        expect(@command.run('--verbose')).to eql('test ')
        expect(@command.proxy_options).to eq([[:verbose, true]])
        expect(@command.run('foo')).to eql('test foo')
        expect(@command.proxy_options).to eq([])
      end
    end

    describe 'should populate options with' do
      it 'boolean values' do
        @command.option '--[no-]toggle'
        @command.when_called { |_, options| expect(options.toggle).to be true }
        @command.run '--toggle'
        @command.when_called { |_, options| expect(options.toggle).to be false }
        @command.run '--no-toggle'
      end

      it 'mandatory arguments' do
        @command.option '--file FILE'
        @command.when_called { |_, options| expect(options.file).to eq('foo') }
        @command.run '--file', 'foo'
        expect { @command.run '--file' }.to raise_error(OptionParser::MissingArgument)
      end

      describe 'optional arguments' do
        before do
          @command.option '--use-config [file] '
        end

        it 'should return the argument when provided' do
          @command.when_called { |_, options| expect(options.use_config).to eq('foo') }
          @command.run '--use-config', 'foo'
        end

        it 'should return true when present without an argument' do
          @command.when_called { |_, options| expect(options.use_config).to be true }
          @command.run '--use-config'
        end

        it 'should return nil when not present' do
          @command.when_called { |_, options| expect(options.use_config).to be_nil }
          @command.run
        end
      end

      describe 'typed arguments' do
        before do
          @command.option '--interval N', Integer
        end

        it 'should parse valid values' do
          @command.when_called { |_, options| expect(options.interval).to eq(5) }
          @command.run '--interval', '5'
        end

        it 'should reject invalid values' do
          expect { @command.run '--interval', 'invalid' }.to raise_error(OptionParser::InvalidArgument)
        end
      end

      it 'lists' do
        @command.option '--fav COLORS', Array
        @command.when_called { |_, options| expect(options.fav).to eq(%w(red green blue)) }
        @command.run '--fav', 'red,green,blue'
      end

      it 'lists with multi-word items' do
        @command.option '--fav MOVIES', Array
        @command.when_called { |_, options| expect(options.fav).to eq(['super\ bad', 'nightmare']) }
        @command.run '--fav', 'super\ bad,nightmare'
      end

      it 'defaults' do
        @command.option '--files LIST', Array
        @command.option '--interval N', Integer
        @command.when_called do |_, options|
          options.default \
            files: %w(foo bar),
            interval: 5
          expect(options.files).to eq(%w(foo bar))
          expect(options.interval).to eq(15)
        end
        @command.run '--interval', '15'
      end

      describe 'given a global option' do
        before do
          @command.global_options << [:global_option, 'gvalue']
        end

        describe 'and no command specific arguments' do
          it 'provides the global option to the command action' do
            @command.when_called { |_, options| expect(options.global_option).to eq('gvalue') }
            @command.run
          end
        end

        describe 'and a command specific option' do
          it 'provides the global option to the command action' do
            @command.when_called { |_, options| expect(options.global_option).to eq('gvalue') }
            @command.run '--verbose'
          end
        end

        describe 'and a command specific argument' do
          it 'provides the global option to the command action' do
            @command.when_called { |_, options| expect(options.global_option).to eq('gvalue') }
            @command.run 'argument'
          end
        end
      end
    end
  end
end