command_kit 0.1.0.pre1
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.
- checksums.yaml +7 -0
- data/.document +3 -0
- data/.github/workflows/ruby.yml +29 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +29 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +20 -0
- data/README.md +283 -0
- data/Rakefile +23 -0
- data/command_kit.gemspec +60 -0
- data/gemspec.yml +14 -0
- data/lib/command_kit.rb +1 -0
- data/lib/command_kit/arguments.rb +161 -0
- data/lib/command_kit/arguments/argument.rb +111 -0
- data/lib/command_kit/arguments/argument_value.rb +81 -0
- data/lib/command_kit/arguments/usage.rb +6 -0
- data/lib/command_kit/colors.rb +355 -0
- data/lib/command_kit/command.rb +42 -0
- data/lib/command_kit/command_name.rb +95 -0
- data/lib/command_kit/commands.rb +299 -0
- data/lib/command_kit/commands/auto_load.rb +153 -0
- data/lib/command_kit/commands/auto_load/subcommand.rb +90 -0
- data/lib/command_kit/commands/auto_require.rb +138 -0
- data/lib/command_kit/commands/command.rb +12 -0
- data/lib/command_kit/commands/help.rb +43 -0
- data/lib/command_kit/commands/parent_command.rb +21 -0
- data/lib/command_kit/commands/subcommand.rb +51 -0
- data/lib/command_kit/console.rb +141 -0
- data/lib/command_kit/description.rb +89 -0
- data/lib/command_kit/env.rb +43 -0
- data/lib/command_kit/env/home.rb +71 -0
- data/lib/command_kit/env/path.rb +71 -0
- data/lib/command_kit/examples.rb +99 -0
- data/lib/command_kit/exception_handler.rb +55 -0
- data/lib/command_kit/help.rb +62 -0
- data/lib/command_kit/help/man.rb +125 -0
- data/lib/command_kit/inflector.rb +84 -0
- data/lib/command_kit/main.rb +103 -0
- data/lib/command_kit/options.rb +179 -0
- data/lib/command_kit/options/option.rb +171 -0
- data/lib/command_kit/options/option_value.rb +90 -0
- data/lib/command_kit/options/parser.rb +227 -0
- data/lib/command_kit/options/quiet.rb +53 -0
- data/lib/command_kit/options/usage.rb +6 -0
- data/lib/command_kit/options/verbose.rb +55 -0
- data/lib/command_kit/options/version.rb +62 -0
- data/lib/command_kit/os.rb +47 -0
- data/lib/command_kit/pager.rb +115 -0
- data/lib/command_kit/printing.rb +32 -0
- data/lib/command_kit/printing/indent.rb +78 -0
- data/lib/command_kit/program_name.rb +57 -0
- data/lib/command_kit/stdio.rb +138 -0
- data/lib/command_kit/usage.rb +102 -0
- data/lib/command_kit/version.rb +4 -0
- data/lib/command_kit/xdg.rb +138 -0
- data/spec/arguments/argument_spec.rb +169 -0
- data/spec/arguments/argument_value_spec.rb +126 -0
- data/spec/arguments_spec.rb +213 -0
- data/spec/colors_spec.rb +470 -0
- data/spec/command_kit_spec.rb +8 -0
- data/spec/command_name_spec.rb +130 -0
- data/spec/command_spec.rb +49 -0
- data/spec/commands/auto_load/subcommand_spec.rb +82 -0
- data/spec/commands/auto_load_spec.rb +128 -0
- data/spec/commands/auto_require_spec.rb +142 -0
- data/spec/commands/fixtures/test_auto_load/cli/commands/test1.rb +10 -0
- data/spec/commands/fixtures/test_auto_load/cli/commands/test2.rb +10 -0
- data/spec/commands/fixtures/test_auto_require/lib/test_auto_require/cli/commands/test1.rb +10 -0
- data/spec/commands/help_spec.rb +66 -0
- data/spec/commands/parent_command_spec.rb +40 -0
- data/spec/commands/subcommand_spec.rb +99 -0
- data/spec/commands_spec.rb +767 -0
- data/spec/console_spec.rb +201 -0
- data/spec/description_spec.rb +203 -0
- data/spec/env/home_spec.rb +46 -0
- data/spec/env/path_spec.rb +78 -0
- data/spec/env_spec.rb +123 -0
- data/spec/examples_spec.rb +235 -0
- data/spec/exception_handler_spec.rb +103 -0
- data/spec/help_spec.rb +119 -0
- data/spec/inflector_spec.rb +104 -0
- data/spec/main_spec.rb +179 -0
- data/spec/options/option_spec.rb +258 -0
- data/spec/options/option_value_spec.rb +67 -0
- data/spec/options/parser_spec.rb +265 -0
- data/spec/options_spec.rb +137 -0
- data/spec/os_spec.rb +46 -0
- data/spec/pager_spec.rb +154 -0
- data/spec/printing/indent_spec.rb +130 -0
- data/spec/printing_spec.rb +76 -0
- data/spec/program_name_spec.rb +62 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/stdio_spec.rb +264 -0
- data/spec/usage_spec.rb +237 -0
- data/spec/xdg_spec.rb +191 -0
- metadata +156 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'command_kit/arguments/argument_value'
|
|
3
|
+
|
|
4
|
+
describe CommandKit::Arguments::ArgumentValue do
|
|
5
|
+
let(:type) { String }
|
|
6
|
+
let(:required) { false }
|
|
7
|
+
let(:default) { "foo" }
|
|
8
|
+
let(:usage) { 'FOO' }
|
|
9
|
+
|
|
10
|
+
subject do
|
|
11
|
+
described_class.new(
|
|
12
|
+
type: type,
|
|
13
|
+
required: required,
|
|
14
|
+
default: default,
|
|
15
|
+
usage: usage
|
|
16
|
+
)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe "#initialize" do
|
|
20
|
+
it "must require a usage: keyword"do
|
|
21
|
+
expect {
|
|
22
|
+
described_class.new(type: type, required: required, default: default)
|
|
23
|
+
}.to raise_error(ArgumentError)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context "when type: is given" do
|
|
27
|
+
subject { described_class.new(type: type, usage: usage) }
|
|
28
|
+
|
|
29
|
+
it "must set #type" do
|
|
30
|
+
expect(subject.type).to eq(type)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context "when type: is not given" do
|
|
35
|
+
subject { described_class.new(usage: usage) }
|
|
36
|
+
|
|
37
|
+
it "must default to nil" do
|
|
38
|
+
expect(subject.type).to be_nil
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context "when required: is given" do
|
|
43
|
+
subject { described_class.new(required: required, usage: usage) }
|
|
44
|
+
|
|
45
|
+
it "must set #required" do
|
|
46
|
+
expect(subject.required).to eq(required)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context "when required: is not given" do
|
|
51
|
+
subject { described_class.new(usage: usage) }
|
|
52
|
+
|
|
53
|
+
it "must default to true" do
|
|
54
|
+
expect(subject.required).to be(true)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context "when default: is given" do
|
|
59
|
+
subject { described_class.new(default: default, usage: usage) }
|
|
60
|
+
|
|
61
|
+
it "must set #default" do
|
|
62
|
+
expect(subject.default).to eq(default)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
context "when default: is not given" do
|
|
67
|
+
subject { described_class.new(usage: usage) }
|
|
68
|
+
|
|
69
|
+
it "must default to nil" do
|
|
70
|
+
expect(subject.default).to be_nil
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
describe "#required?" do
|
|
76
|
+
context "when required: is initialized with true" do
|
|
77
|
+
let(:required) { true }
|
|
78
|
+
|
|
79
|
+
it { expect(subject.required?).to be(true) }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
context "when required: is initialized with false" do
|
|
83
|
+
let(:required) { false }
|
|
84
|
+
|
|
85
|
+
it { expect(subject.required?).to be(false) }
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
describe "#optional?" do
|
|
90
|
+
context "when required: is initialized with true" do
|
|
91
|
+
let(:required) { true }
|
|
92
|
+
|
|
93
|
+
it { expect(subject.optional?).to be(false) }
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
context "when required: is initialized with false" do
|
|
97
|
+
let(:required) { false }
|
|
98
|
+
|
|
99
|
+
it { expect(subject.optional?).to be(true) }
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
describe "#default_value" do
|
|
104
|
+
context "when initialized with a default: that responded to #call" do
|
|
105
|
+
let(:default) do
|
|
106
|
+
->{ [] }
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "must call the default #call method" do
|
|
110
|
+
expect(subject.default_value).to eq(default.call)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
context "when initialized with a default: that it's an Object" do
|
|
115
|
+
let(:default) { "" }
|
|
116
|
+
|
|
117
|
+
it "must return the default: object" do
|
|
118
|
+
expect(subject.default_value).to eq(default)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it "must duplicate the default: object each time" do
|
|
122
|
+
expect(subject.default_value).to_not be(subject.default_value)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'command_kit/arguments'
|
|
3
|
+
|
|
4
|
+
describe Arguments do
|
|
5
|
+
module TestArguments
|
|
6
|
+
class ImplicitCmd
|
|
7
|
+
include CommandKit::Arguments
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
let(:command_class) { TestArguments::ImplicitCmd }
|
|
12
|
+
|
|
13
|
+
describe ".arguments" do
|
|
14
|
+
subject { TestArguments::ImplicitCmd }
|
|
15
|
+
|
|
16
|
+
context "when no arguments have been defined" do
|
|
17
|
+
it "should default to {}" do
|
|
18
|
+
expect(subject.arguments).to eq({})
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context "when a arguments is explicitly set" do
|
|
23
|
+
module TestArguments
|
|
24
|
+
class ExplicitCmd
|
|
25
|
+
include CommandKit::Arguments
|
|
26
|
+
argument :foo, desc: 'Foo option'
|
|
27
|
+
argument :bar, desc: 'Bar option'
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
subject { TestArguments::ExplicitCmd }
|
|
32
|
+
|
|
33
|
+
it "must return the explicitly set arguments" do
|
|
34
|
+
expect(subject.arguments.keys).to eq([:foo, :bar])
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
context "when the command class inherites from another class" do
|
|
39
|
+
context "but no arguments are defined" do
|
|
40
|
+
module TestArguments
|
|
41
|
+
class BaseCmd
|
|
42
|
+
include CommandKit::Arguments
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class InheritedCmd < BaseCmd
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
subject { TestArguments::InheritedCmd }
|
|
50
|
+
|
|
51
|
+
it "must search each class then return {}"do
|
|
52
|
+
expect(subject.arguments).to eq({})
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
module TestArguments
|
|
57
|
+
class ExplicitBaseCmd
|
|
58
|
+
include CommandKit::Arguments
|
|
59
|
+
argument :foo, desc: 'Foo option'
|
|
60
|
+
argument :bar, desc: 'Bar option'
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context "when the superclass defines arguments" do
|
|
65
|
+
module TestArguments
|
|
66
|
+
class ImplicitInheritedCmd < ExplicitBaseCmd
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
let(:super_subject) { TestArguments::ExplicitBaseCmd }
|
|
71
|
+
subject { TestArguments::ImplicitInheritedCmd }
|
|
72
|
+
|
|
73
|
+
it "must inherit the superclass'es arguments" do
|
|
74
|
+
expect(subject.arguments).to eq(super_subject.arguments)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "must not change the superclass'es arguments" do
|
|
78
|
+
expect(super_subject.arguments.keys).to eq([:foo, :bar])
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
context "when the subclass defines arguments" do
|
|
83
|
+
module TestArguments
|
|
84
|
+
class ImplicitBaseCmd
|
|
85
|
+
include CommandKit::Arguments
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
class ExplicitInheritedCmd < ImplicitBaseCmd
|
|
89
|
+
argument :baz, desc: 'Baz option'
|
|
90
|
+
argument :qux, desc: 'Qux option'
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
let(:super_subject) { TestArguments::ImplicitBaseCmd }
|
|
95
|
+
subject { TestArguments::ExplicitInheritedCmd }
|
|
96
|
+
|
|
97
|
+
it "must return the subclass'es arguments" do
|
|
98
|
+
expect(subject.arguments.keys).to eq([:baz, :qux])
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it "must not change the superclass'es arguments" do
|
|
102
|
+
expect(super_subject.arguments).to eq({})
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
context "when subclass overrides the superclass's argumentss" do
|
|
107
|
+
module TestArguments
|
|
108
|
+
class ExplicitOverridingInheritedCmd < ExplicitBaseCmd
|
|
109
|
+
argument :foo, desc: "Overriden foo option"
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
let(:super_subject) { TestArguments::ExplicitBaseCmd }
|
|
114
|
+
subject { TestArguments::ExplicitOverridingInheritedCmd }
|
|
115
|
+
|
|
116
|
+
it "must combine the superclass'es arguments with the subclass'es" do
|
|
117
|
+
expect(subject.arguments.keys).to eq([:foo, :bar])
|
|
118
|
+
expect(subject.arguments[:foo].desc).to eq("Overriden foo option")
|
|
119
|
+
expect(subject.arguments[:bar].desc).to eq("Bar option")
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it "must not change the superclass'es arguments" do
|
|
123
|
+
expect(super_subject.arguments.keys).to eq([:foo, :bar])
|
|
124
|
+
expect(super_subject.arguments[:foo].desc).to eq("Foo option")
|
|
125
|
+
expect(super_subject.arguments[:bar].desc).to eq("Bar option")
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
subject { command_class.new }
|
|
132
|
+
|
|
133
|
+
describe "#help_arguments" do
|
|
134
|
+
context "when #arguments returns {}" do
|
|
135
|
+
module TestArguments
|
|
136
|
+
class NoArguments
|
|
137
|
+
include CommandKit::Arguments
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
let(:command_class) { TestArguments::NoArguments }
|
|
142
|
+
subject { command_class.new }
|
|
143
|
+
|
|
144
|
+
it "must print out the arguments" do
|
|
145
|
+
expect { subject.help_arguments }.to_not output.to_stdout
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
context "when #arguments returns an Array" do
|
|
150
|
+
module TestArguments
|
|
151
|
+
class MultipleArguments
|
|
152
|
+
include CommandKit::Arguments
|
|
153
|
+
|
|
154
|
+
argument :foo, desc: "Foo option"
|
|
155
|
+
argument :bar, desc: "Bar option"
|
|
156
|
+
argument :baz, desc: "Baz option"
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
let(:command_class) { TestArguments::MultipleArguments }
|
|
161
|
+
subject { command_class.new }
|
|
162
|
+
|
|
163
|
+
let(:foo_argument) { command_class.arguments[:foo] }
|
|
164
|
+
let(:bar_argument) { command_class.arguments[:bar] }
|
|
165
|
+
let(:baz_argument) { command_class.arguments[:baz] }
|
|
166
|
+
|
|
167
|
+
it "must print out the 'Arguments:' section header and the arguments" do
|
|
168
|
+
expect { subject.help_arguments }.to output(
|
|
169
|
+
[
|
|
170
|
+
'',
|
|
171
|
+
"Arguments:",
|
|
172
|
+
" #{foo_argument.usage.ljust(33)}#{foo_argument.desc}",
|
|
173
|
+
" #{bar_argument.usage.ljust(33)}#{bar_argument.desc}",
|
|
174
|
+
" #{baz_argument.usage.ljust(33)}#{baz_argument.desc}",
|
|
175
|
+
''
|
|
176
|
+
].join($/)
|
|
177
|
+
).to_stdout
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
describe "#help" do
|
|
183
|
+
it "must call #help_arguments" do
|
|
184
|
+
expect(subject).to receive(:help_arguments)
|
|
185
|
+
|
|
186
|
+
subject.help
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
context "when the superclass defines it's own #help method" do
|
|
190
|
+
module TestDescription
|
|
191
|
+
class SuperclassHelpMethod
|
|
192
|
+
def help
|
|
193
|
+
puts 'superclass'
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
class InheritedHelpMethod < SuperclassHelpMethod
|
|
198
|
+
include CommandKit::Arguments
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
let(:super_command_class) { TestDescription::SuperclassHelpMethod }
|
|
203
|
+
let(:command_class) { TestDescription::InheritedHelpMethod }
|
|
204
|
+
|
|
205
|
+
it "must call the superclass'es #help method first" do
|
|
206
|
+
expect_any_instance_of(super_command_class).to receive(:help)
|
|
207
|
+
expect(subject).to receive(:help_arguments)
|
|
208
|
+
|
|
209
|
+
subject.help
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
data/spec/colors_spec.rb
ADDED
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'command_kit/colors'
|
|
3
|
+
|
|
4
|
+
describe Colors do
|
|
5
|
+
module TestColors
|
|
6
|
+
class TestCommand
|
|
7
|
+
include CommandKit::Colors
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
let(:command_class) { TestColors::TestCommand }
|
|
12
|
+
subject { command_class.new }
|
|
13
|
+
|
|
14
|
+
it { expect(described_class).to include(Stdio) }
|
|
15
|
+
it { expect(described_class).to include(Env) }
|
|
16
|
+
|
|
17
|
+
describe Colors::ANSI do
|
|
18
|
+
subject { described_class }
|
|
19
|
+
|
|
20
|
+
describe "RESET" do
|
|
21
|
+
it { expect(subject::RESET).to eq("\e[0m") }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "CLEAR" do
|
|
25
|
+
it { expect(subject::CLEAR).to eq("\e[0m") }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe "BOLD" do
|
|
29
|
+
it { expect(subject::BOLD).to eq("\e[1m") }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "RESET_INTENSITY" do
|
|
33
|
+
it { expect(subject::RESET_INTENSITY).to eq("\e[22m") }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe "BLACK" do
|
|
37
|
+
it { expect(subject::BLACK).to eq("\e[30m") }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe "RED" do
|
|
41
|
+
it { expect(subject::RED).to eq("\e[31m") }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe "GREEN" do
|
|
45
|
+
it { expect(subject::GREEN).to eq("\e[32m") }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "YELLOW" do
|
|
49
|
+
it { expect(subject::YELLOW).to eq("\e[33m") }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe "BLUE" do
|
|
53
|
+
it { expect(subject::BLUE).to eq("\e[34m") }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe "MAGENTA" do
|
|
57
|
+
it { expect(subject::MAGENTA).to eq("\e[35m") }
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
describe "CYAN" do
|
|
61
|
+
it { expect(subject::CYAN).to eq("\e[36m") }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe "WHITE" do
|
|
65
|
+
it { expect(subject::WHITE).to eq("\e[37m") }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
describe "RESET_COLOR" do
|
|
69
|
+
it { expect(subject::RESET_COLOR).to eq("\e[39m") }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
let(:str) { 'foo' }
|
|
73
|
+
|
|
74
|
+
describe ".reset" do
|
|
75
|
+
it { expect(subject.reset).to eq(described_class::RESET) }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe ".clear" do
|
|
79
|
+
it { expect(subject.clear).to eq(described_class::CLEAR) }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
describe ".bold" do
|
|
83
|
+
context "when given a string" do
|
|
84
|
+
it "must wrap the string with \\e[1m and \\e[22m" do
|
|
85
|
+
expect(subject.bold(str)).to eq("\e[1m#{str}\e[22m")
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
context "when given no arguments" do
|
|
90
|
+
it { expect(subject.bold).to eq("\e[1m") }
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
describe ".black" do
|
|
95
|
+
context "when given a string" do
|
|
96
|
+
it "must wrap the string with \\e[30m and \\e[39m" do
|
|
97
|
+
expect(subject.black(str)).to eq("\e[30m#{str}\e[39m")
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
context "when given no arguments" do
|
|
102
|
+
it { expect(subject.black).to eq("\e[30m") }
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
describe ".red" do
|
|
107
|
+
context "when given a string" do
|
|
108
|
+
it "must wrap the string with \\e[31m and \\e[39m" do
|
|
109
|
+
expect(subject.red(str)).to eq("\e[31m#{str}\e[39m")
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
context "when given no arguments" do
|
|
114
|
+
it { expect(subject.red).to eq("\e[31m") }
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
describe ".green" do
|
|
119
|
+
context "when given a string" do
|
|
120
|
+
it "must wrap the string with \\e[32m and \\e[39m" do
|
|
121
|
+
expect(subject.green(str)).to eq("\e[32m#{str}\e[39m")
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
context "when given no arguments" do
|
|
126
|
+
it { expect(subject.green).to eq("\e[32m") }
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
describe ".yellow" do
|
|
131
|
+
context "when given a string" do
|
|
132
|
+
it "must wrap the string with \\e[33m and \\e[39m" do
|
|
133
|
+
expect(subject.yellow(str)).to eq("\e[33m#{str}\e[39m")
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
context "when given no arguments" do
|
|
138
|
+
it { expect(subject.yellow).to eq("\e[33m") }
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
describe ".blue" do
|
|
143
|
+
context "when given a string" do
|
|
144
|
+
it "must wrap the string with \\e[34m and \\e[39m" do
|
|
145
|
+
expect(subject.blue(str)).to eq("\e[34m#{str}\e[39m")
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
context "when given no arguments" do
|
|
150
|
+
it { expect(subject.blue).to eq("\e[34m") }
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
describe ".magenta" do
|
|
155
|
+
context "when given a string" do
|
|
156
|
+
it "must wrap the string with \\e[35m and \\e[39m" do
|
|
157
|
+
expect(subject.magenta(str)).to eq("\e[35m#{str}\e[39m")
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
context "when given no arguments" do
|
|
162
|
+
it { expect(subject.magenta).to eq("\e[35m") }
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
describe ".cyan" do
|
|
167
|
+
context "when given a string" do
|
|
168
|
+
it "must wrap the string with \\e[36m and \\e[39m" do
|
|
169
|
+
expect(subject.cyan(str)).to eq("\e[36m#{str}\e[39m")
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
context "when given no arguments" do
|
|
174
|
+
it { expect(subject.cyan).to eq("\e[36m") }
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
describe ".white" do
|
|
179
|
+
context "when given a string" do
|
|
180
|
+
it "must wrap the string with \\e[37m and \\e[39m" do
|
|
181
|
+
expect(subject.white(str)).to eq("\e[37m#{str}\e[39m")
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
context "when given no arguments" do
|
|
186
|
+
it { expect(subject.white).to eq("\e[37m") }
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
describe Colors::PlainText do
|
|
192
|
+
subject { described_class }
|
|
193
|
+
|
|
194
|
+
let(:str) { 'foo' }
|
|
195
|
+
|
|
196
|
+
describe "RESET" do
|
|
197
|
+
it { expect(subject::RESET).to eq('') }
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
describe "CLEAR" do
|
|
201
|
+
it { expect(subject::CLEAR).to eq('') }
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
describe "BOLD" do
|
|
205
|
+
it { expect(subject::BOLD).to eq('') }
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
describe "RESET_INTENSITY" do
|
|
209
|
+
it { expect(subject::RESET_INTENSITY).to eq('') }
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
describe "BLACK" do
|
|
213
|
+
it { expect(subject::BLACK).to eq('') }
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
describe "RED" do
|
|
217
|
+
it { expect(subject::RED).to eq('') }
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
describe "GREEN" do
|
|
221
|
+
it { expect(subject::GREEN).to eq('') }
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
describe "YELLOW" do
|
|
225
|
+
it { expect(subject::YELLOW).to eq('') }
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
describe "BLUE" do
|
|
229
|
+
it { expect(subject::BLUE).to eq('') }
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
describe "MAGENTA" do
|
|
233
|
+
it { expect(subject::MAGENTA).to eq('') }
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
describe "CYAN" do
|
|
237
|
+
it { expect(subject::CYAN).to eq('') }
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
describe "WHITE" do
|
|
241
|
+
it { expect(subject::WHITE).to eq('') }
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
describe "RESET_COLOR" do
|
|
245
|
+
it { expect(subject::RESET_COLOR).to eq('') }
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
describe ".reset" do
|
|
249
|
+
it { expect(subject.reset).to eq('') }
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
describe ".clear" do
|
|
253
|
+
it { expect(subject.clear).to eq('') }
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
describe ".bold" do
|
|
257
|
+
context "when given a string" do
|
|
258
|
+
it "must return that string" do
|
|
259
|
+
expect(subject.bold(str)).to eq(str)
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
context "when given no arguments" do
|
|
264
|
+
it { expect(subject.bold).to eq('') }
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
describe ".black" do
|
|
269
|
+
context "when given a string" do
|
|
270
|
+
it "must return that string" do
|
|
271
|
+
expect(subject.black(str)).to eq(str)
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
context "when given no arguments" do
|
|
276
|
+
it { expect(subject.black).to eq('') }
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
describe ".red" do
|
|
281
|
+
context "when given a string" do
|
|
282
|
+
it "must return that string" do
|
|
283
|
+
expect(subject.red(str)).to eq(str)
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
context "when given no arguments" do
|
|
288
|
+
it { expect(subject.red).to eq('') }
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
describe ".green" do
|
|
293
|
+
context "when given a string" do
|
|
294
|
+
it "must return that string" do
|
|
295
|
+
expect(subject.green(str)).to eq(str)
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
context "when given no arguments" do
|
|
300
|
+
it { expect(subject.green).to eq('') }
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
describe ".yellow" do
|
|
305
|
+
context "when given a string" do
|
|
306
|
+
it "must return that string" do
|
|
307
|
+
expect(subject.yellow(str)).to eq(str)
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
context "when given no arguments" do
|
|
312
|
+
it { expect(subject.yellow).to eq('') }
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
describe ".blue" do
|
|
317
|
+
context "when given a string" do
|
|
318
|
+
it "must return that string" do
|
|
319
|
+
expect(subject.blue(str)).to eq(str)
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
context "when given no arguments" do
|
|
324
|
+
it { expect(subject.blue).to eq('') }
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
describe ".magenta" do
|
|
329
|
+
context "when given a string" do
|
|
330
|
+
it "must return that string" do
|
|
331
|
+
expect(subject.magenta(str)).to eq(str)
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
context "when given no arguments" do
|
|
336
|
+
it { expect(subject.magenta).to eq('') }
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
describe ".cyan" do
|
|
341
|
+
context "when given a string" do
|
|
342
|
+
it "must return that string" do
|
|
343
|
+
expect(subject.cyan(str)).to eq(str)
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
context "when given no arguments" do
|
|
348
|
+
it { expect(subject.cyan).to eq('') }
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
describe ".white" do
|
|
353
|
+
context "when given a string" do
|
|
354
|
+
it "must return that string" do
|
|
355
|
+
expect(subject.white(str)).to eq(str)
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
context "when given no arguments" do
|
|
360
|
+
it { expect(subject.white).to eq('') }
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
describe "#ansi?" do
|
|
366
|
+
context "when TERM='dumb'" do
|
|
367
|
+
subject { command_class.new(env: {'TERM' => 'dumb'}) }
|
|
368
|
+
|
|
369
|
+
it { expect(subject.ansi?).to be(false) }
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
context "when stdout is a TTY" do
|
|
373
|
+
let(:stdout) { StringIO.new }
|
|
374
|
+
subject { command_class.new(stdout: stdout) }
|
|
375
|
+
|
|
376
|
+
before { allow(stdout).to receive(:tty?).and_return(true) }
|
|
377
|
+
|
|
378
|
+
it { expect(subject.ansi?).to be(true) }
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
context "when stdout is not a TTY" do
|
|
382
|
+
let(:stdout) { StringIO.new }
|
|
383
|
+
subject { command_class.new(stdout: stdout) }
|
|
384
|
+
|
|
385
|
+
it { expect(subject.ansi?).to be(false) }
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
context "when given an alternate stream" do
|
|
389
|
+
context "and the alternate stream is a TTY" do
|
|
390
|
+
let(:stream) { StringIO.new }
|
|
391
|
+
|
|
392
|
+
before { allow(stream).to receive(:tty?).and_return(true) }
|
|
393
|
+
|
|
394
|
+
it { expect(subject.ansi?(stream)).to be(true) }
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
context "but the alternate stream is not a TTY" do
|
|
398
|
+
let(:stream) { StringIO.new }
|
|
399
|
+
|
|
400
|
+
it { expect(subject.ansi?(stream)).to be(false) }
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
describe "#colors" do
|
|
406
|
+
context "when stdout supports ANSI" do
|
|
407
|
+
let(:stdout) { StringIO.new }
|
|
408
|
+
subject { command_class.new(stdout: stdout) }
|
|
409
|
+
|
|
410
|
+
before { allow(stdout).to receive(:tty?).and_return(true) }
|
|
411
|
+
|
|
412
|
+
it { expect(subject.colors).to be(Colors::ANSI) }
|
|
413
|
+
|
|
414
|
+
context "when a block is given" do
|
|
415
|
+
it do
|
|
416
|
+
expect { |b|
|
|
417
|
+
subject.colors(&b)
|
|
418
|
+
}.to yield_with_args(Colors::ANSI)
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
context "when stdout does not support ANSI" do
|
|
424
|
+
let(:stdout) { StringIO.new }
|
|
425
|
+
subject { command_class.new(stdout: stdout) }
|
|
426
|
+
|
|
427
|
+
it { expect(subject.colors).to be(Colors::PlainText) }
|
|
428
|
+
|
|
429
|
+
context "when a block is given" do
|
|
430
|
+
it do
|
|
431
|
+
expect { |b|
|
|
432
|
+
subject.colors(&b)
|
|
433
|
+
}.to yield_with_args(Colors::PlainText)
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
context "when given an alternate stream" do
|
|
439
|
+
context "and the alternate stream supports ANSI" do
|
|
440
|
+
let(:stream) { StringIO.new }
|
|
441
|
+
|
|
442
|
+
before { allow(stream).to receive(:tty?).and_return(true) }
|
|
443
|
+
|
|
444
|
+
it { expect(subject.colors(stream)).to be(Colors::ANSI) }
|
|
445
|
+
|
|
446
|
+
context "when a block is given" do
|
|
447
|
+
it do
|
|
448
|
+
expect { |b|
|
|
449
|
+
subject.colors(stream,&b)
|
|
450
|
+
}.to yield_with_args(Colors::ANSI)
|
|
451
|
+
end
|
|
452
|
+
end
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
context "but the alternate stream does not support ANSI" do
|
|
456
|
+
let(:stream) { StringIO.new }
|
|
457
|
+
|
|
458
|
+
it { expect(subject.colors(stream)).to be(Colors::PlainText) }
|
|
459
|
+
|
|
460
|
+
context "when a block is given" do
|
|
461
|
+
it do
|
|
462
|
+
expect { |b|
|
|
463
|
+
subject.colors(stream,&b)
|
|
464
|
+
}.to yield_with_args(Colors::PlainText)
|
|
465
|
+
end
|
|
466
|
+
end
|
|
467
|
+
end
|
|
468
|
+
end
|
|
469
|
+
end
|
|
470
|
+
end
|