cuprum-cli 0.1.0

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.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +34 -0
  3. data/CODE_OF_CONDUCT.md +10 -0
  4. data/LICENSE +21 -0
  5. data/README.md +163 -0
  6. data/lib/cuprum/cli/argument.rb +172 -0
  7. data/lib/cuprum/cli/arguments/class_methods.rb +283 -0
  8. data/lib/cuprum/cli/arguments.rb +16 -0
  9. data/lib/cuprum/cli/coercion.rb +131 -0
  10. data/lib/cuprum/cli/command.rb +102 -0
  11. data/lib/cuprum/cli/commands/ci/report.rb +121 -0
  12. data/lib/cuprum/cli/commands/ci/rspec_command.rb +108 -0
  13. data/lib/cuprum/cli/commands/ci/rspec_each_command.rb +185 -0
  14. data/lib/cuprum/cli/commands/ci.rb +12 -0
  15. data/lib/cuprum/cli/commands/echo_command.rb +76 -0
  16. data/lib/cuprum/cli/commands/file/generate_file.rb +141 -0
  17. data/lib/cuprum/cli/commands/file/new_command.rb +86 -0
  18. data/lib/cuprum/cli/commands/file/render_erb.rb +88 -0
  19. data/lib/cuprum/cli/commands/file/resolve_template.rb +136 -0
  20. data/lib/cuprum/cli/commands/file/templates/rspec.rb.erb +14 -0
  21. data/lib/cuprum/cli/commands/file/templates/ruby.rb.erb +29 -0
  22. data/lib/cuprum/cli/commands/file/templates.rb +71 -0
  23. data/lib/cuprum/cli/commands/file.rb +14 -0
  24. data/lib/cuprum/cli/commands.rb +12 -0
  25. data/lib/cuprum/cli/dependencies/file_system/mock.rb +297 -0
  26. data/lib/cuprum/cli/dependencies/file_system.rb +247 -0
  27. data/lib/cuprum/cli/dependencies/standard_io/helpers.rb +138 -0
  28. data/lib/cuprum/cli/dependencies/standard_io/mock.rb +85 -0
  29. data/lib/cuprum/cli/dependencies/standard_io.rb +110 -0
  30. data/lib/cuprum/cli/dependencies/system_command/mock.rb +57 -0
  31. data/lib/cuprum/cli/dependencies/system_command.rb +147 -0
  32. data/lib/cuprum/cli/dependencies.rb +25 -0
  33. data/lib/cuprum/cli/errors/files/file_not_writeable.rb +42 -0
  34. data/lib/cuprum/cli/errors/files/missing_parameter.rb +71 -0
  35. data/lib/cuprum/cli/errors/files/missing_template.rb +36 -0
  36. data/lib/cuprum/cli/errors/files/template_error.rb +37 -0
  37. data/lib/cuprum/cli/errors/files/template_not_resolved.rb +54 -0
  38. data/lib/cuprum/cli/errors/files.rb +19 -0
  39. data/lib/cuprum/cli/errors/system_command_failure.rb +44 -0
  40. data/lib/cuprum/cli/errors.rb +11 -0
  41. data/lib/cuprum/cli/integrations/thor/arguments_parser.rb +99 -0
  42. data/lib/cuprum/cli/integrations/thor/registry.rb +42 -0
  43. data/lib/cuprum/cli/integrations/thor/task.rb +211 -0
  44. data/lib/cuprum/cli/integrations/thor.rb +14 -0
  45. data/lib/cuprum/cli/integrations.rb +8 -0
  46. data/lib/cuprum/cli/metadata.rb +215 -0
  47. data/lib/cuprum/cli/option.rb +165 -0
  48. data/lib/cuprum/cli/options/class_methods.rb +232 -0
  49. data/lib/cuprum/cli/options/quiet.rb +32 -0
  50. data/lib/cuprum/cli/options/verbose.rb +32 -0
  51. data/lib/cuprum/cli/options.rb +18 -0
  52. data/lib/cuprum/cli/registry.rb +141 -0
  53. data/lib/cuprum/cli/rspec/deferred/arguments_examples.rb +203 -0
  54. data/lib/cuprum/cli/rspec/deferred/ci/report_examples.rb +450 -0
  55. data/lib/cuprum/cli/rspec/deferred/ci.rb +8 -0
  56. data/lib/cuprum/cli/rspec/deferred/dependencies/file_system_examples.rb +1469 -0
  57. data/lib/cuprum/cli/rspec/deferred/dependencies.rb +8 -0
  58. data/lib/cuprum/cli/rspec/deferred/metadata_examples.rb +856 -0
  59. data/lib/cuprum/cli/rspec/deferred/options_examples.rb +234 -0
  60. data/lib/cuprum/cli/rspec/deferred/registry_examples.rb +451 -0
  61. data/lib/cuprum/cli/rspec/deferred.rb +8 -0
  62. data/lib/cuprum/cli/rspec.rb +8 -0
  63. data/lib/cuprum/cli/version.rb +59 -0
  64. data/lib/cuprum/cli.rb +47 -0
  65. metadata +173 -0
@@ -0,0 +1,856 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspec/sleeping_king_studios/deferred/provider'
4
+
5
+ require 'cuprum/cli/rspec/deferred'
6
+
7
+ module Cuprum::Cli::RSpec::Deferred
8
+ # Deferred examples for testing command metadata.
9
+ module MetadataExamples
10
+ include RSpec::SleepingKingStudios::Deferred::Provider
11
+
12
+ deferred_examples 'should implement the Metadata interface' do
13
+ describe '.abstract' do
14
+ it 'should define the class method' do
15
+ expect(described_class)
16
+ .to respond_to(:abstract)
17
+ .with(0).arguments
18
+ end
19
+ end
20
+
21
+ describe '.abstract?' do
22
+ it 'should define the class predicate' do
23
+ expect(described_class)
24
+ .to define_predicate(:abstract?)
25
+ end
26
+ end
27
+
28
+ describe '.description' do
29
+ it 'should define the class method' do
30
+ expect(described_class)
31
+ .to respond_to(:description)
32
+ .with(0..1).arguments
33
+ end
34
+ end
35
+
36
+ describe '.description?' do
37
+ it 'should define the class predicate' do
38
+ expect(described_class)
39
+ .to define_predicate(:description?)
40
+ end
41
+ end
42
+
43
+ describe '.full_description' do
44
+ it 'should define the class method' do
45
+ expect(described_class)
46
+ .to respond_to(:full_description)
47
+ .with(0..1).arguments
48
+ end
49
+ end
50
+
51
+ describe '.full_description?' do
52
+ it 'should define the class predicate' do
53
+ expect(described_class)
54
+ .to define_predicate(:full_description?)
55
+ end
56
+ end
57
+
58
+ describe '.full_name' do
59
+ it 'should define the class method' do
60
+ expect(described_class)
61
+ .to respond_to(:full_name)
62
+ .with(0..1).arguments
63
+ end
64
+ end
65
+
66
+ describe '.namespace' do
67
+ include_examples 'should define class reader', :namespace
68
+ end
69
+
70
+ describe '.namespace?' do
71
+ it 'should define the class predicate' do
72
+ expect(described_class)
73
+ .to define_predicate(:namespace?)
74
+ end
75
+ end
76
+
77
+ describe '.short_name' do
78
+ include_examples 'should define class reader', :short_name
79
+ end
80
+ end
81
+
82
+ deferred_examples 'should define metadata for the command' do
83
+ describe '.abstract' do
84
+ it 'should mark the command as abstract' do
85
+ expect { described_class.abstract }
86
+ .to change(described_class, :abstract?)
87
+ .to be true
88
+ end
89
+ end
90
+
91
+ describe '.abstract?' do
92
+ it { expect(described_class.abstract?).to be false }
93
+
94
+ context 'when the command is abstract' do
95
+ before(:example) do
96
+ described_class.abstract
97
+ end
98
+
99
+ it { expect(described_class.abstract?).to be true }
100
+ end
101
+
102
+ wrap_deferred 'when the command has a parent command' do
103
+ it { expect(described_class.abstract?).to be false }
104
+
105
+ context 'when the command is abstract' do
106
+ before(:example) do
107
+ described_class.abstract
108
+ end
109
+
110
+ it { expect(described_class.abstract?).to be true }
111
+ end
112
+
113
+ context 'when the parent command is abstract' do
114
+ before(:example) do
115
+ parent_class.abstract
116
+ end
117
+
118
+ it { expect(described_class.abstract?).to be false }
119
+ end
120
+ end
121
+ end
122
+
123
+ describe '.description' do
124
+ describe 'with no arguments' do
125
+ it { expect(described_class.description).to be nil }
126
+ end
127
+
128
+ describe 'with nil' do
129
+ let(:error_message) do
130
+ tools.assertions.error_message_for('presence', as: 'description')
131
+ end
132
+
133
+ it 'should raise an exception' do
134
+ expect { described_class.description(nil) }
135
+ .to raise_error ArgumentError, error_message
136
+ end
137
+ end
138
+
139
+ describe 'with an Object' do
140
+ let(:error_message) do
141
+ tools.assertions.error_message_for('name', as: 'description')
142
+ end
143
+
144
+ it 'should raise an exception' do
145
+ expect { described_class.description(Object.new.freeze) }
146
+ .to raise_error ArgumentError, error_message
147
+ end
148
+ end
149
+
150
+ describe 'with an empty String' do
151
+ let(:error_message) do
152
+ tools.assertions.error_message_for('presence', as: 'description')
153
+ end
154
+
155
+ it 'should raise an exception' do
156
+ expect { described_class.description('') }
157
+ .to raise_error ArgumentError, error_message
158
+ end
159
+ end
160
+
161
+ describe 'with a non-empty String' do
162
+ let(:value) do
163
+ 'No one is quite sure what this does.'
164
+ end
165
+
166
+ it { expect(described_class.description(value)).to be == value }
167
+
168
+ it 'should set the description' do
169
+ expect { described_class.description(value) }
170
+ .to change(described_class, :description)
171
+ .to be == value
172
+ end
173
+ end
174
+
175
+ context 'when the command is abstract' do
176
+ let(:value) do
177
+ 'No one is quite sure what this does.'
178
+ end
179
+ let(:error_message) do
180
+ 'unable to set description - Spec::CustomCommand is an abstract ' \
181
+ 'class'
182
+ end
183
+
184
+ before(:example) { described_class.abstract }
185
+
186
+ it 'should raise an exception' do
187
+ expect { described_class.description(value) }.to raise_error(
188
+ described_class::AbstractCommandError,
189
+ error_message
190
+ )
191
+ end
192
+ end
193
+
194
+ wrap_deferred 'when the command has a parent command' do
195
+ it { expect(described_class.description).to be nil }
196
+
197
+ context 'when the command has a description' do
198
+ let(:description) do
199
+ 'No one is quite sure what this does.'
200
+ end
201
+
202
+ before(:example) do
203
+ described_class.description(description)
204
+ end
205
+
206
+ it { expect(described_class.description).to be == description }
207
+ end
208
+
209
+ context 'when the parent command has a description' do
210
+ let(:parent_description) do
211
+ 'A thing of mystery.'
212
+ end
213
+
214
+ before(:example) do
215
+ parent_class.description(parent_description)
216
+ end
217
+
218
+ it 'should return the parent description' do
219
+ expect(described_class.description).to be == parent_description
220
+ end
221
+
222
+ context 'when the command has a description' do
223
+ let(:description) do
224
+ 'No one is quite sure what this does.'
225
+ end
226
+
227
+ before(:example) do
228
+ described_class.description(description)
229
+ end
230
+
231
+ it { expect(described_class.description).to be == description }
232
+ end
233
+ end
234
+ end
235
+ end
236
+
237
+ describe '.description?' do
238
+ it { expect(described_class.description?).to be false }
239
+
240
+ context 'when the command has a description' do
241
+ let(:description) do
242
+ 'No one is quite sure what this does.'
243
+ end
244
+
245
+ before(:example) do
246
+ described_class.description(description)
247
+ end
248
+
249
+ it { expect(described_class.description?).to be true }
250
+ end
251
+
252
+ wrap_deferred 'when the command has a parent command' do
253
+ it { expect(described_class.description?).to be false }
254
+
255
+ context 'when the command has a description' do
256
+ let(:description) do
257
+ 'No one is quite sure what this does.'
258
+ end
259
+
260
+ before(:example) do
261
+ described_class.description(description)
262
+ end
263
+
264
+ it { expect(described_class.description?).to be true }
265
+ end
266
+
267
+ context 'when the parent command has a description' do
268
+ let(:parent_description) do
269
+ 'A thing of mystery.'
270
+ end
271
+
272
+ before(:example) do
273
+ Spec::CustomCommand.description(parent_description)
274
+ end
275
+
276
+ it { expect(described_class.description?).to be true }
277
+ end
278
+ end
279
+ end
280
+
281
+ describe '.full_description' do
282
+ describe 'with no arguments' do
283
+ it { expect(described_class.full_description).to be nil }
284
+ end
285
+
286
+ describe 'with nil' do
287
+ let(:error_message) do
288
+ tools
289
+ .assertions
290
+ .error_message_for('presence', as: 'full_description')
291
+ end
292
+
293
+ it 'should raise an exception' do
294
+ expect { described_class.full_description(nil) }
295
+ .to raise_error ArgumentError, error_message
296
+ end
297
+ end
298
+
299
+ describe 'with an Object' do
300
+ let(:error_message) do
301
+ tools.assertions.error_message_for('name', as: 'full_description')
302
+ end
303
+
304
+ it 'should raise an exception' do
305
+ expect { described_class.full_description(Object.new.freeze) }
306
+ .to raise_error ArgumentError, error_message
307
+ end
308
+ end
309
+
310
+ describe 'with an empty String' do
311
+ let(:error_message) do
312
+ tools
313
+ .assertions
314
+ .error_message_for('presence', as: 'full_description')
315
+ end
316
+
317
+ it 'should raise an exception' do
318
+ expect { described_class.full_description('') }
319
+ .to raise_error ArgumentError, error_message
320
+ end
321
+ end
322
+
323
+ describe 'with a non-empty String' do
324
+ let(:value) do
325
+ <<~DESC
326
+ No one is quite sure what this does.
327
+
328
+ ...but it sure looks cool!
329
+ DESC
330
+ end
331
+
332
+ it { expect(described_class.full_description(value)).to be == value }
333
+
334
+ it 'should set the full description' do
335
+ expect { described_class.full_description(value) }
336
+ .to change(described_class, :full_description)
337
+ .to be == value
338
+ end
339
+ end
340
+
341
+ context 'when the command has a description' do
342
+ let(:description) do
343
+ 'No one is quite sure what this does.'
344
+ end
345
+
346
+ before(:example) do
347
+ described_class.description(description)
348
+ end
349
+
350
+ it { expect(described_class.full_description).to be == description }
351
+
352
+ describe 'with a non-empty String' do
353
+ let(:value) do
354
+ <<~DESC
355
+ No one is quite sure what this does.
356
+
357
+ ...but it sure looks cool!
358
+ DESC
359
+ end
360
+
361
+ it 'should return the value' do
362
+ expect(described_class.full_description(value)).to be == value
363
+ end
364
+
365
+ it 'should set the full description' do
366
+ expect { described_class.full_description(value) }
367
+ .to change(described_class, :full_description)
368
+ .to be == value
369
+ end
370
+ end
371
+ end
372
+
373
+ wrap_deferred 'when the command has a parent command' do
374
+ it { expect(described_class.full_description).to be nil }
375
+
376
+ context 'when the command has a description' do
377
+ let(:description) do
378
+ 'No one is quite sure what this does.'
379
+ end
380
+
381
+ before(:example) do
382
+ described_class.description(description)
383
+ end
384
+
385
+ it { expect(described_class.full_description).to be == description }
386
+
387
+ context 'when the command has a full description' do
388
+ let(:full_description) do
389
+ <<~DESC
390
+ No one is quite sure what this does.
391
+
392
+ ...but it sure looks cool!
393
+ DESC
394
+ end
395
+
396
+ before(:example) do
397
+ described_class.full_description(full_description)
398
+ end
399
+
400
+ it 'should return the full description' do
401
+ expect(described_class.full_description)
402
+ .to be == full_description
403
+ end
404
+ end
405
+ end
406
+
407
+ context 'when the command has a full description' do
408
+ let(:full_description) do
409
+ <<~DESC
410
+ No one is quite sure what this does.
411
+
412
+ ...but it sure looks cool!
413
+ DESC
414
+ end
415
+
416
+ before(:example) do
417
+ described_class.full_description(full_description)
418
+ end
419
+
420
+ it 'should return the full description' do
421
+ expect(described_class.full_description).to be == full_description
422
+ end
423
+ end
424
+
425
+ context 'when the parent command has a description' do
426
+ let(:parent_description) do
427
+ 'A thing of mystery.'
428
+ end
429
+
430
+ before(:example) do
431
+ Spec::CustomCommand.description(parent_description)
432
+ end
433
+
434
+ it 'should return the parent value' do
435
+ expect(described_class.full_description)
436
+ .to be == parent_description
437
+ end
438
+
439
+ context 'when the command has a description' do
440
+ let(:description) do
441
+ 'No one is quite sure what this does.'
442
+ end
443
+
444
+ before(:example) do
445
+ described_class.description(description)
446
+ end
447
+
448
+ it 'should return the description' do
449
+ expect(described_class.full_description).to be == description
450
+ end
451
+ end
452
+
453
+ context 'when the command has a full description' do
454
+ let(:full_description) do
455
+ <<~DESC
456
+ No one is quite sure what this does.
457
+
458
+ ...but it sure looks cool!
459
+ DESC
460
+ end
461
+
462
+ before(:example) do
463
+ described_class.full_description(full_description)
464
+ end
465
+
466
+ it 'should return the full description' do
467
+ expect(described_class.full_description)
468
+ .to be == full_description
469
+ end
470
+ end
471
+ end
472
+
473
+ context 'when the parent command has a full description' do
474
+ let(:parent_description) do
475
+ 'A thing of mystery.'
476
+ end
477
+
478
+ before(:example) do
479
+ Spec::CustomCommand.full_description(parent_description)
480
+ end
481
+
482
+ it 'should return the parent value' do
483
+ expect(described_class.full_description)
484
+ .to be == parent_description
485
+ end
486
+
487
+ context 'when the command has a description' do
488
+ let(:description) do
489
+ 'No one is quite sure what this does.'
490
+ end
491
+
492
+ before(:example) do
493
+ described_class.description(description)
494
+ end
495
+
496
+ it 'should return the parent value' do
497
+ expect(described_class.full_description)
498
+ .to be == parent_description
499
+ end
500
+ end
501
+
502
+ context 'when the command has a full description' do
503
+ let(:full_description) do
504
+ <<~DESC
505
+ No one is quite sure what this does.
506
+
507
+ ...but it sure looks cool!
508
+ DESC
509
+ end
510
+
511
+ before(:example) do
512
+ described_class.full_description(full_description)
513
+ end
514
+
515
+ it 'should return the full description' do
516
+ expect(described_class.full_description)
517
+ .to be == full_description
518
+ end
519
+ end
520
+ end
521
+ end
522
+
523
+ context 'when the command is abstract' do
524
+ let(:value) do
525
+ <<~DESC
526
+ No one is quite sure what this does.
527
+
528
+ ...but it sure looks cool!
529
+ DESC
530
+ end
531
+ let(:error_message) do
532
+ 'unable to set full_description - Spec::CustomCommand is an ' \
533
+ 'abstract class'
534
+ end
535
+
536
+ before(:example) { described_class.abstract }
537
+
538
+ it 'should raise an exception' do
539
+ expect { described_class.full_description(value) }.to raise_error(
540
+ described_class::AbstractCommandError,
541
+ error_message
542
+ )
543
+ end
544
+ end
545
+ end
546
+
547
+ describe '.full_description?' do
548
+ it { expect(described_class.full_description?).to be false }
549
+
550
+ context 'when the command has a description' do
551
+ let(:description) do
552
+ 'No one is quite sure what this does.'
553
+ end
554
+
555
+ before(:example) do
556
+ described_class.description(description)
557
+ end
558
+
559
+ it { expect(described_class.full_description?).to be false }
560
+ end
561
+
562
+ context 'when the command has a full description' do
563
+ let(:full_description) do
564
+ <<~DESC
565
+ No one is quite sure what this does.
566
+
567
+ ...but it sure looks cool!
568
+ DESC
569
+ end
570
+
571
+ before(:example) do
572
+ described_class.full_description(full_description)
573
+ end
574
+
575
+ it { expect(described_class.full_description?).to be true }
576
+ end
577
+
578
+ wrap_deferred 'when the command has a parent command' do
579
+ context 'when the command has a description' do
580
+ let(:description) do
581
+ 'No one is quite sure what this does.'
582
+ end
583
+
584
+ before(:example) do
585
+ described_class.description(description)
586
+ end
587
+
588
+ it { expect(described_class.full_description?).to be false }
589
+ end
590
+
591
+ context 'when the command has a full description' do
592
+ let(:full_description) do
593
+ <<~DESC
594
+ No one is quite sure what this does.
595
+
596
+ ...but it sure looks cool!
597
+ DESC
598
+ end
599
+
600
+ before(:example) do
601
+ described_class.full_description(full_description)
602
+ end
603
+
604
+ it { expect(described_class.full_description?).to be true }
605
+ end
606
+
607
+ context 'when the parent command has a description' do
608
+ let(:parent_description) do
609
+ 'A thing of mystery.'
610
+ end
611
+
612
+ before(:example) do
613
+ Spec::CustomCommand.description(parent_description)
614
+ end
615
+
616
+ it { expect(described_class.full_description?).to be false }
617
+ end
618
+
619
+ context 'when the parent command has a full description' do
620
+ let(:parent_description) do
621
+ 'A thing of mystery.'
622
+ end
623
+
624
+ before(:example) do
625
+ Spec::CustomCommand.full_description(parent_description)
626
+ end
627
+
628
+ it { expect(described_class.full_description?).to be true }
629
+ end
630
+ end
631
+ end
632
+
633
+ describe '.full_name' do
634
+ let(:expected) { 'spec:custom' }
635
+
636
+ describe 'with no arguments' do
637
+ it { expect(described_class.full_name).to be == expected }
638
+
639
+ wrap_deferred 'when the command is an anonymous class' do
640
+ it { expect(described_class.full_name).to be nil }
641
+ end
642
+
643
+ context 'when the namespace includes ::Commands' do
644
+ let(:expected) { 'scope:do_something' }
645
+ let(:described_class) do
646
+ Spec::Namespace::Commands::Scope::DoSomething
647
+ end
648
+
649
+ example_class 'Spec::Namespace::Commands::Scope::DoSomething',
650
+ 'Spec::CustomCommand'
651
+
652
+ it { expect(described_class.full_name).to be == expected }
653
+ end
654
+ end
655
+
656
+ describe 'with nil' do
657
+ let(:error_message) do
658
+ tools.assertions.error_message_for('presence', as: 'full_name')
659
+ end
660
+
661
+ it 'should raise an exception' do
662
+ expect { described_class.full_name(nil) }
663
+ .to raise_error ArgumentError, error_message
664
+ end
665
+ end
666
+
667
+ describe 'with an Object' do
668
+ let(:error_message) do
669
+ tools.assertions.error_message_for('name', as: 'full_name')
670
+ end
671
+
672
+ it 'should raise an exception' do
673
+ expect { described_class.full_name(Object.new.freeze) }
674
+ .to raise_error ArgumentError, error_message
675
+ end
676
+ end
677
+
678
+ describe 'with an empty String' do
679
+ let(:error_message) do
680
+ tools.assertions.error_message_for('presence', as: 'full_name')
681
+ end
682
+
683
+ it 'should raise an exception' do
684
+ expect { described_class.full_name('') }
685
+ .to raise_error ArgumentError, error_message
686
+ end
687
+ end
688
+
689
+ describe 'with an invalid String' do
690
+ let(:error_message) do
691
+ 'full_name does not match format category:sub_category:do_something'
692
+ end
693
+
694
+ it 'should raise an exception' do
695
+ expect { described_class.full_name(described_class.name) }
696
+ .to raise_error ArgumentError, error_message
697
+ end
698
+ end
699
+
700
+ describe 'with an valid String' do
701
+ let(:value) { 'do_something' }
702
+
703
+ it { expect(described_class.full_name(value)).to be == value }
704
+
705
+ it 'should set the full name' do
706
+ expect { described_class.full_name(value) }
707
+ .to change(described_class, :full_name)
708
+ .to be == value
709
+ end
710
+ end
711
+
712
+ describe 'with an valid scoped String' do
713
+ let(:value) { 'category:sub_category:do_something' }
714
+
715
+ it { expect(described_class.full_name(value)).to be == value }
716
+
717
+ it 'should set the full name' do
718
+ expect { described_class.full_name(value) }
719
+ .to change(described_class, :full_name)
720
+ .to be == value
721
+ end
722
+ end
723
+
724
+ wrap_deferred 'when the command has a parent command' do
725
+ let(:expected) { 'spec:subclass' }
726
+
727
+ it { expect(described_class.full_name).to be == expected }
728
+
729
+ wrap_deferred 'when the command is an anonymous class' do
730
+ let(:expected) { 'spec:custom' }
731
+
732
+ it { expect(described_class.full_name).to be == expected }
733
+
734
+ context 'when the parent command defines a full name' do
735
+ let(:expected) { 'category:sub_category:do_something' }
736
+
737
+ before(:example) do
738
+ parent_class.full_name 'category:sub_category:do_something'
739
+ end
740
+
741
+ it { expect(described_class.full_name).to be == expected }
742
+ end
743
+
744
+ context 'when the parent command is an anonymous class' do
745
+ let(:parent_class) do
746
+ Class.new do
747
+ include Cuprum::Cli::Metadata
748
+
749
+ def self.name
750
+ Class.instance_method(:name).bind(self).call
751
+ end
752
+ end
753
+ end
754
+
755
+ it { expect(described_class.full_name).to be nil }
756
+ end
757
+ end
758
+ end
759
+
760
+ context 'when the command is abstract' do
761
+ let(:value) { 'category:sub_category:do_something' }
762
+ let(:error_message) do
763
+ 'unable to set full_name - Spec::CustomCommand is an abstract class'
764
+ end
765
+
766
+ before(:example) { described_class.abstract }
767
+
768
+ it 'should raise an exception' do
769
+ expect { described_class.full_name(value) }.to raise_error(
770
+ described_class::AbstractCommandError,
771
+ error_message
772
+ )
773
+ end
774
+ end
775
+ end
776
+
777
+ describe '.namespace' do
778
+ it { expect(described_class.namespace).to be == 'spec' }
779
+
780
+ wrap_deferred 'when the command is an anonymous class' do
781
+ it { expect(described_class.namespace).to be nil }
782
+ end
783
+
784
+ context 'when the command has an unscoped name' do
785
+ before(:example) do
786
+ described_class.full_name 'do_something'
787
+ end
788
+
789
+ it { expect(described_class.namespace).to be nil }
790
+ end
791
+
792
+ context 'when the command has a scoped name' do
793
+ let(:expected) { 'category:sub_category' }
794
+
795
+ before(:example) do
796
+ described_class.full_name 'category:sub_category:do_something'
797
+ end
798
+
799
+ it { expect(described_class.namespace).to be == expected }
800
+ end
801
+ end
802
+
803
+ describe '.namespace?' do
804
+ it { expect(described_class.namespace?).to be true }
805
+
806
+ wrap_deferred 'when the command is an anonymous class' do
807
+ it { expect(described_class.namespace?).to be false }
808
+ end
809
+
810
+ context 'when the command has an unscoped name' do
811
+ before(:example) do
812
+ described_class.full_name 'do_something'
813
+ end
814
+
815
+ it { expect(described_class.namespace?).to be false }
816
+ end
817
+
818
+ context 'when the command has a scoped name' do
819
+ let(:expected) { 'category:sub_category' }
820
+
821
+ before(:example) do
822
+ described_class.full_name 'category:sub_category:do_something'
823
+ end
824
+
825
+ it { expect(described_class.namespace?).to be true }
826
+ end
827
+ end
828
+
829
+ describe '.short_name' do
830
+ let(:expected) { 'custom' }
831
+
832
+ it { expect(described_class.short_name).to be == expected }
833
+
834
+ context 'when the command is an anonymous class' do
835
+ let(:described_class) do
836
+ Class.new do
837
+ include Cuprum::Cli::Metadata
838
+ end
839
+ end
840
+
841
+ it { expect(described_class.short_name).to be nil }
842
+ end
843
+
844
+ context 'when the command has a custom name' do
845
+ let(:expected) { 'do_something' }
846
+
847
+ before(:example) do
848
+ described_class.full_name 'category:sub_category:do_something'
849
+ end
850
+
851
+ it { expect(described_class.short_name).to be == expected }
852
+ end
853
+ end
854
+ end
855
+ end
856
+ end