command_kit 0.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +7 -0
  2. data/.document +3 -0
  3. data/.github/workflows/ruby.yml +29 -0
  4. data/.gitignore +7 -0
  5. data/.rspec +1 -0
  6. data/.yardopts +1 -0
  7. data/ChangeLog.md +29 -0
  8. data/Gemfile +14 -0
  9. data/LICENSE.txt +20 -0
  10. data/README.md +283 -0
  11. data/Rakefile +23 -0
  12. data/command_kit.gemspec +60 -0
  13. data/gemspec.yml +14 -0
  14. data/lib/command_kit.rb +1 -0
  15. data/lib/command_kit/arguments.rb +161 -0
  16. data/lib/command_kit/arguments/argument.rb +111 -0
  17. data/lib/command_kit/arguments/argument_value.rb +81 -0
  18. data/lib/command_kit/arguments/usage.rb +6 -0
  19. data/lib/command_kit/colors.rb +355 -0
  20. data/lib/command_kit/command.rb +42 -0
  21. data/lib/command_kit/command_name.rb +95 -0
  22. data/lib/command_kit/commands.rb +299 -0
  23. data/lib/command_kit/commands/auto_load.rb +153 -0
  24. data/lib/command_kit/commands/auto_load/subcommand.rb +90 -0
  25. data/lib/command_kit/commands/auto_require.rb +138 -0
  26. data/lib/command_kit/commands/command.rb +12 -0
  27. data/lib/command_kit/commands/help.rb +43 -0
  28. data/lib/command_kit/commands/parent_command.rb +21 -0
  29. data/lib/command_kit/commands/subcommand.rb +51 -0
  30. data/lib/command_kit/console.rb +141 -0
  31. data/lib/command_kit/description.rb +89 -0
  32. data/lib/command_kit/env.rb +43 -0
  33. data/lib/command_kit/env/home.rb +71 -0
  34. data/lib/command_kit/env/path.rb +71 -0
  35. data/lib/command_kit/examples.rb +99 -0
  36. data/lib/command_kit/exception_handler.rb +55 -0
  37. data/lib/command_kit/help.rb +62 -0
  38. data/lib/command_kit/help/man.rb +125 -0
  39. data/lib/command_kit/inflector.rb +84 -0
  40. data/lib/command_kit/main.rb +103 -0
  41. data/lib/command_kit/options.rb +179 -0
  42. data/lib/command_kit/options/option.rb +171 -0
  43. data/lib/command_kit/options/option_value.rb +90 -0
  44. data/lib/command_kit/options/parser.rb +227 -0
  45. data/lib/command_kit/options/quiet.rb +53 -0
  46. data/lib/command_kit/options/usage.rb +6 -0
  47. data/lib/command_kit/options/verbose.rb +55 -0
  48. data/lib/command_kit/options/version.rb +62 -0
  49. data/lib/command_kit/os.rb +47 -0
  50. data/lib/command_kit/pager.rb +115 -0
  51. data/lib/command_kit/printing.rb +32 -0
  52. data/lib/command_kit/printing/indent.rb +78 -0
  53. data/lib/command_kit/program_name.rb +57 -0
  54. data/lib/command_kit/stdio.rb +138 -0
  55. data/lib/command_kit/usage.rb +102 -0
  56. data/lib/command_kit/version.rb +4 -0
  57. data/lib/command_kit/xdg.rb +138 -0
  58. data/spec/arguments/argument_spec.rb +169 -0
  59. data/spec/arguments/argument_value_spec.rb +126 -0
  60. data/spec/arguments_spec.rb +213 -0
  61. data/spec/colors_spec.rb +470 -0
  62. data/spec/command_kit_spec.rb +8 -0
  63. data/spec/command_name_spec.rb +130 -0
  64. data/spec/command_spec.rb +49 -0
  65. data/spec/commands/auto_load/subcommand_spec.rb +82 -0
  66. data/spec/commands/auto_load_spec.rb +128 -0
  67. data/spec/commands/auto_require_spec.rb +142 -0
  68. data/spec/commands/fixtures/test_auto_load/cli/commands/test1.rb +10 -0
  69. data/spec/commands/fixtures/test_auto_load/cli/commands/test2.rb +10 -0
  70. data/spec/commands/fixtures/test_auto_require/lib/test_auto_require/cli/commands/test1.rb +10 -0
  71. data/spec/commands/help_spec.rb +66 -0
  72. data/spec/commands/parent_command_spec.rb +40 -0
  73. data/spec/commands/subcommand_spec.rb +99 -0
  74. data/spec/commands_spec.rb +767 -0
  75. data/spec/console_spec.rb +201 -0
  76. data/spec/description_spec.rb +203 -0
  77. data/spec/env/home_spec.rb +46 -0
  78. data/spec/env/path_spec.rb +78 -0
  79. data/spec/env_spec.rb +123 -0
  80. data/spec/examples_spec.rb +235 -0
  81. data/spec/exception_handler_spec.rb +103 -0
  82. data/spec/help_spec.rb +119 -0
  83. data/spec/inflector_spec.rb +104 -0
  84. data/spec/main_spec.rb +179 -0
  85. data/spec/options/option_spec.rb +258 -0
  86. data/spec/options/option_value_spec.rb +67 -0
  87. data/spec/options/parser_spec.rb +265 -0
  88. data/spec/options_spec.rb +137 -0
  89. data/spec/os_spec.rb +46 -0
  90. data/spec/pager_spec.rb +154 -0
  91. data/spec/printing/indent_spec.rb +130 -0
  92. data/spec/printing_spec.rb +76 -0
  93. data/spec/program_name_spec.rb +62 -0
  94. data/spec/spec_helper.rb +6 -0
  95. data/spec/stdio_spec.rb +264 -0
  96. data/spec/usage_spec.rb +237 -0
  97. data/spec/xdg_spec.rb +191 -0
  98. 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
@@ -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